Skip to content

Instantly share code, notes, and snippets.

@mbakeranalecta
Created July 27, 2015 15:11
Show Gist options
  • Save mbakeranalecta/e271db0ece5e89a91e49 to your computer and use it in GitHub Desktop.
Save mbakeranalecta/e271db0ece5e89a91e49 to your computer and use it in GitHub Desktop.
Complex grouping in XSLT
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:output indent="yes"/>
<xsl:variable name="f">
<x g="green" n="1. Just green"/>
<x g="foo ; bar" n="2. The bar of foo"/>
<x g="foo; baz" n="3. The baz of foo"/>
<x g="green ;blue" n="4. Turquoise 1"/>
<x g="green; red" n='5. Brown study'/>
<x g="foo" n="6. Pure foo"/>
<x g="bar;red" n='7. The red bar'/>
<x g="foo; bar" n="8. More bar of foo"/>
<x g="foo ;baz" n="9. More baz of foo"/>
<x g="green ;blue" n="10. Turquoise 2"/>
</xsl:variable>
<xsl:template name="main">
<groups>
<xsl:call-template name="group-stuff">
<xsl:with-param name="stuff" select="$f/x"/>
<xsl:with-param name="level">1</xsl:with-param>
</xsl:call-template>
</groups>
</xsl:template>
<xsl:template name="group-stuff">
<xsl:param name="stuff"/>
<xsl:param name="level" as="xs:integer"/>
<xsl:for-each-group select="$stuff" group-by="tokenize(@g,'\s*;\s*')[$level]">
<group>
<name><xsl:value-of select="current-grouping-key()"/></name>
<xsl:for-each select="current-group()/.">
<xsl:if test="not(tokenize(@g,'\s*;\s*')[$level+1])">
<title><xsl:value-of select="string(@n)"/></title>
</xsl:if>
</xsl:for-each>
<xsl:call-template name="group-stuff">
<xsl:with-param name="stuff" select="current-group()"/>
<xsl:with-param name="level" select="$level+1"/>
</xsl:call-template>
</group>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment