XML/XSLT stylesheet/Grouping
Addresses grouped by zip code
File: Data.xml
<?xml version="1.0"?>
<addressbook>
<address>
<name>
<title>Mr.</title>
<first-name>C</first-name>
<last-name>F</last-name>
</name>
<street>1234 Main Street</street>
<city>Vancouver</city>
<state>WI</state>
<zip>48392</zip>
</address>
</addressbook>
File: Transform.xslt
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:text>Addresses grouped by zip code 
</xsl:text>
<xsl:for-each select="addressbook/address">
<xsl:sort select="zip"/>
<xsl:if test="zip!=preceding-sibling::address[1]/zip">
<xsl:text>
Zip code </xsl:text>
<xsl:value-of select="zip"/>
<xsl:text> (</xsl:text>
<xsl:value-of select="city"/>
<xsl:text>, </xsl:text>
<xsl:value-of select="state"/>
<xsl:text>): 
</xsl:text>
</xsl:if>
<xsl:if test="name/title">
<xsl:value-of select="name/title"/>
<xsl:text> </xsl:text>
</xsl:if>
<xsl:value-of select="name/first-name"/>
<xsl:text> </xsl:text>
<xsl:value-of select="name/last-name"/>
<xsl:text>
</xsl:text>
<xsl:value-of select="street"/>
<xsl:text>

</xsl:text>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Output:
Addresses grouped by zip code
Mr. C F
1234 Main Street
Grouping in XSLT
File: Data.xml
<?xml version="1.0"?>
<html>
<body>
<h2>A</h2>
<p class="item">A</p>
<p class="item">B</p>
<p class="note">C</p>
<p class="note">D</p>
<p class="note">E</p>
<p class="item">F</p>
<h2>B</h2>
<p class="item">b1</p>
<p class="item">b2</p>
<p class="note">b3</p>
<p class="item">b4</p>
</body>
</html>
File: Transform.xslt
<?xml version="1.0"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<chapter>
<title>Grouping in XSLT</title>
<xsl:apply-templates select="html/body"/>
</chapter>
</xsl:template>
<xsl:template match="body">
<xsl:for-each-group select="*" group-starting-with="h1">
<sect1>
<xsl:apply-templates select="current-group()"/>
</sect1>
</xsl:for-each-group>
</xsl:template>
<xsl:template match="h1">
<title>
<xsl:apply-templates/>
</title>
</xsl:template>
<xsl:template match="p">
<para>
<xsl:apply-templates/>
</para>
</xsl:template>
<xsl:template match="*">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Output:
<?xml version="1.0" encoding="UTF-8"?>
<chapter>
<title>Grouping in XSLT</title>
<sect1>
<h2>A</h2>
<para>A</para>
<para>B</para>
<para>C</para>
<para>D</para>
<para>E</para>
<para>F</para>
<h2>B</h2>
<para>b1</para>
<para>b2</para>
<para>b3</para>
<para>b4</para>
</sect1>
</chapter>
Grouping with group-adjacent
File: Data.xml
<?xml version="1.0"?>
<html>
<body>
<h2>A</h2>
<p class="item">A <code>key</code>.</p>
<p class="item">B</p>
<p class="note">C</p>
<p class="note">D</p>
<p class="note">E</p>
<p class="item">F.</p>
<h2>B</h2>
<p class="item">G</p>
<p class="item">H</p>
<p class="note">T</p>
<p class="item">I</p>
</body>
</html>
File: Transform.xslt
<?xml version="1.0"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" include-content-type="no"/>
<xsl:template match="/">
<html>
<head>
<title>Grouping with group-adjacent</title>
</head>
<body>
<xsl:for-each-group select="html/body/*"
group-adjacent="boolean(self::p)">
<xsl:choose>
<xsl:when test="current-grouping-key()">
<ul>
<xsl:for-each select="current-group()">
<li>
<xsl:copy-of select="@*"/>
<xsl:apply-templates select="*|text()"/>
</li>
</xsl:for-each>
</ul>
</xsl:when>
<xsl:otherwise>
<xsl:for-each select="current-group()">
<xsl:apply-templates select="."/>
</xsl:for-each>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</body>
</html>
</xsl:template>
<xsl:template match="*">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Output:
<html>
<head>
<title>Grouping with group-adjacent</title>
</head>
<body>
<h2>A</h2>
<ul>
<li class="item">A <code>key</code>.
</li>
<li class="item">B</li>
<li class="note">C</li>
<li class="note">D</li>
<li class="note">E</li>
<li class="item">F.</li>
</ul>
<h2>B</h2>
<ul>
<li class="item">G</li>
<li class="item">H</li>
<li class="note">T</li>
<li class="item">I</li>
</ul>
</body>
</html>