首页 > 解决方案 > XSLT group on child node

问题描述

I'am try to convert XML on group of child nodes. Main information is in bill node, it must be group by bill numbers.

original XML, this is simplified version of original XML

<items>
    <item>  
        <bill>10</bill>  
        <name>first (10)</name>
        <price>111</price>
    </item>
    <item>
        <bill>10</bill>
        <name>second (10)</name>
        <price>222</price>
    </item>
    <item>
        <bill>10</bill>
        <name>third (10)</name>
        <price>333</price>
    </item>
    <item>
        <bill>11</bill>
        <name>first (11)</name>
        <price>1</price>
    </item>
    <item>
        <bill>11</bill>
        <name>second (11)</name>
        <price>2</price>
    </item>
</items>

final file

<bills>
    <bill>
        <number>10</number>
        <items>
            <item>
                <nameitem>first (10)</nameitem>
                <priceitem>111</priceitem>
            </item>
            <item>
                <nameitem>second (10)</nameitem>
                <priceitem>222</priceitem>
            </item>
            <item>
                <nameitem>third (10)</nameitem>
                <priceitem>333</priceitem>
            </item>
        </items>
    </bill>
    <bill>
        <number>11</number>
        <items>
            <item>
                <nameitem>first (11)</nameitem>
                <priceitem>1</priceitem>
            </item>
            <item>
                <nameitem>second (11)</nameitem>
                <priceitem>2</priceitem>
            </item>
        </items>
    </bill>
</bills>

there is working XSLT, for basic grouping, but I have not idea, how to build another structure inside bill node, based on final XML

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="group-by-bill" match="item" use="bill"/>

<xsl:template match="items">
    <bills>
        <xsl:for-each select="item[generate-id()=generate-id (key('group-by-bill', bill)[1])]">
            <bill number="{bill}">
                <xsl:copy-of select="key('group-by-bill', bill)"/>
            </bill>
        </xsl:for-each>
    </bills>
</xsl:template>

标签: group-byxslt-1.0

解决方案


用这个:

<xsl:template match="items">
    <bills>
        <xsl:for-each select="item[generate-id()=generate-id (key('group-by-bill', bill)[1])]">
            <bill>
                <number><xsl:value-of select="bill"/></number>
                <items>
                    <xsl:for-each select="//item[bill = current()/bill]">
                        <item>
                            <xsl:copy-of select="name|price"/>
                        </item>
                    </xsl:for-each>
                </items>
            </bill>
        </xsl:for-each>
    </bills>
</xsl:template>

请参阅https://xsltfiddle.liberty-development.net/jyH9rM5上的转换


推荐阅读