For XSLT 1.0, the grouping method is performed using the muenchian method, for example:
(source: http://www.jenitennison.com/xslt/grouping/muenchian.html )
We have XML:
<records> <contact id="0001"> <title>Mr</title> <forename>John</forename> <surname>Smith</surname> </contact> <contact id="0002"> <title>Dr</title> <forename>Amy</forename> <surname>Jones</surname> </contact> ... </records>
And we will not group by last name and print the following result:
Jones,<br /> Amy (Dr)<br /> Brian (Mr)<br /> Smith,<br /> Fiona (Ms)<br /> John (Mr)<br />
This is done using the following template and XSLT 1.0 key:
<xsl:key name="contacts-by-surname" match="contact" use="surname" /> <xsl:template match="records"> <xsl:for-each select="contact[count(. | key('contacts-by-surname', surname)[1]) = 1]"> <xsl:sort select="surname" /> <xsl:value-of select="surname" />,<br /> <xsl:for-each select="key('contacts-by-surname', surname)"> <xsl:sort select="forename" /> <xsl:value-of select="forename" /> (<xsl:value-of select="title" />)<br /> </xsl:for-each> </xsl:for-each> </xsl:template>
The template for your problem will look like this (untested):
<xsl:key name="page-by-country" match="page" use="property[@name='country']/value/item/@name" /> <xsl:template match="pages"> <xsl:for-each select="page[count(. | key('page-by-country', property[@name='country']/value/item/@name)[1]) = 1]"> <xsl:sort select="property[@name='country']/value/item/@name" /> <h1><xsl:value-of select="property[@name='country']/value/item/@name" /></h1> <xsl:for-each select="key('page-by-country', property[@name='country']/value/item/@name)"> <xsl:sort select="name" /> <h2><xsl:value-of select="name"/></h2> </xsl:for-each> </xsl:for-each> </xsl:template>
See this working example for your problem: xsltransform.net
source share