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...
Relational databases have always offered a feature known as grouping, that is, sorting a collection of records on a field or combination of fields and then treating each subcollection that has the same value in that sort key as a unit.
The value used to select the items in the current group. The current-grouping-key() function is only useful inside an <xsl:for-each-group> element with a group-by or group-adjacent attribute. Calling current-grouping-key() anywhere else returns the empty sequence.
XSLT (Extensible Stylesheet Language Transformations) is a language originally designed for transforming XML documents into other XML documents, or other formats such as HTML for web pages, plain text or XSL Formatting Objects, which may subsequently be converted to other formats, such as PDF, PostScript and PNG.
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>
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With