Rate this page

Flattr this

Group XML elements by key using XSLT v2.0

Tested with Saxon on

Debian (Lenny, Squeeze)
Ubuntu (Intrepid, Jaunty, Karmic, Lucid, Maverick, Natty, Precise, Trusty)

Objective

To organise a set of XML elements into groups, such that elements with the same key are placed in the same group, and elements with different keys are placed in different groups

Scenario

See Group XML elements by key using XSLT.

Method

XSLT v2.0 introduced direct support for grouping my means of the for-each-group element. This is more readable than the Muenchian method, and potentially more efficient too. The only significant drawback is that an XSLT v2.0-compatible processor is needed. (At the time of writing Saxon supported XSLT v2.0 but xsltproc and Xalan did not.)

Within a for-each-group element, the functions current-grouping-key and current-group can be used to gain access to the current value of the key and the set of nodes that correspond to that key.

Here is a complete stylesheet to perform the task specified in the scenario (grouping Subversion log entries by path):

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

<xsl:template match="/log">
 <log>
  <xsl:for-each-group select="//path" group-by="text()">
   <pathentry>
    <path><xsl:value-of select="current-grouping-key()"/></path>
    <xsl:for-each select="current-group()">
     <logentry>
      <xsl:attribute name="revision"><xsl:value-of select="ancestor::logentry/@revision"/></xsl:attribute>
      <xsl:attribute name="action"><xsl:value-of select="@action"/></xsl:attribute>
      <xsl:attribute name="date"><xsl:value-of select="ancestor::logentry/date/text()"/></xsl:attribute>
     </logentry>
    </xsl:for-each>
   </pathentry>
  </xsl:for-each-group>
 </log>
</xsl:template>
</xsl:stylesheet>

Testing

For sample input and output documents see Group XML elements by key using XSLT.

To apply the stylesheet using Saxon see Process an XML document using an XSLT stylesheet.

At the time of writing this stylesheet is not expected to work with xsltproc or Xalan due to lack of XSLT v2.0 compatibility.

See also