How to use group by in xslt

2020-03-03 06:31发布

I have a xml that has so many elements and most of that contain attributes.. for some of the attributes values are same so I need to group them and generate diff xml. I/p Ex:

<TestNode>
 <ABC1 value="10.7" format="$" />
 <ABC2 value="10.5" format="$" />
 <ABC3 value="20" format="Rs" />
 <ABC4 value="50" format="Rs" />
 <ABC5 value="10.5" format="$" />
</TestNode>

I need to group the rows by format. Note: Format is not fixed... it may grow ... O/P Ex: is it possible to get ? Thanks in advance...

标签: xslt group-by
2条回答
我只想做你的唯一
2楼-- · 2020-03-03 06:42

In XSLT 2.0 you should be able to do it with <xsl:for-each-group>, current-grouping-key() and current-group()

Example:

<xsl:for-each-group 
    select="TestNode/*"
    group-by="@format"
>
    <group format="{current-grouping-key()}">
        <xsl:for-each select="current-group()">
            <xsl:copy-of select="."/>
        </xsl:for-each>
    </group>
</xsl:for-each-group>

See: http://www.w3.org/TR/xslt20/#grouping

查看更多
▲ chillily
3楼-- · 2020-03-03 06:50

In XSLT 1.0 you would use Muenchian grouping.

Define a key "format", from which we can easily select all elements given a format name. Than apply Muenchian grouping to find the unique formats in the input.

Then it gets simple. The "*" template will be applied once per format, and uses the key() to fetch all entries for that format.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:output method="xml" indent="yes" />

    <xsl:key name="format" match="TestNode/*" use="@format" />

    <xsl:template match="TestNode">
        <body>
            <xsl:apply-templates select="*[generate-id(.)=generate-id(key('format',@format)[1])]"/>
        </body>
    </xsl:template>

    <xsl:template match="*">
        <format format="{@format}">
          <xsl:copy-of select="key('format', @format)" />
        </format>
    </xsl:template>

</xsl:stylesheet>
查看更多
登录 后发表回答