使用XSLT执行数据透视

AJ.*_*AJ. 5 xslt pivot

我有一个像这样的xml文件:

<root>
    <item>
        <name>one</name>
        <status>good</status>
    </item>
    <item>
        <name>two</name>
        <status>good</status>
    </item>
    <item>
        <name>three</name>
        <status>bad</status>
    </item>
    <item>
        <name>four</name>
        <status>ugly</status>
    </item>
    <item>
        <name>five</name>
        <status>bad</status>
    </item>
</root>
Run Code Online (Sandbox Code Playgroud)

我想使用XSLT将其转换为:

<root>
    <items><status>good</status>
        <name>one</name>
        <name>two</name>
    </items>
    <items><status>bad</status>
        <name>three</name>
        <name>five</name>
    </items>
    <items><status>ugly</status>
        <name>four</name>
    </items>
</root>
Run Code Online (Sandbox Code Playgroud)

换句话说,我得到一个项目列表,每个项目都有一个状态,我想把它变成一个状态列表,每个状态都有一个项目列表.

我最初的想法是依次匹配每个状态类型的apply-templates,但这意味着我必须知道完整的状态列表.有没有更好的方法呢?

谢谢你的帮助.

ann*_*ata 7

Muench救援!

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:output method="xml" indent="yes" encoding="UTF-8"/>

    <xsl:key name="muench" match="/root/item/status" use="."/>

    <xsl:template match="/">
        <root>
        <xsl:for-each select="/root/item/status[generate-id() = generate-id(key('muench',.)[1])]">
            <xsl:call-template name="pivot">
                <xsl:with-param name="status" select="."/>
            </xsl:call-template>
        </xsl:for-each>
        </root>
    </xsl:template>

    <xsl:template name="pivot">
        <xsl:param name="status"/>
        <items>
            <status><xsl:value-of select="$status"/></status>
            <xsl:for-each select="/root/item[status=$status]">
                <name><xsl:value-of select="name"/></name>
            </xsl:for-each>
        </items>
    </xsl:template>

</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)