XSLT - Grouping with Keys
Since XSLT 1.0 doesn’t have built-in grouping, we use the Muenchian Method, which relies on <xsl:key>
.
Grouping with Keys (Muenchian Method)
Steps
-
Define a key to index nodes by the grouping property.
-
Select only the first occurrence of each group (using
generate-id()
). -
Inside that, use the
key()
function to fetch all nodes that belong to that group.
Example XML
<library>
<book>
<title>XML Basics</title>
<author>Alice</author>
</book>
<book>
<title>XSLT in Action</title>
<author>Bob</author>
</book>
<book>
<title>Advanced XML</title>
<author>Alice</author>
</book>
<book>
<title>XPath Mastery</title>
<author>Bob</author>
</book>
</library>
XSLT with Grouping
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<!-- 1. Define a key: group books by author -->
<xsl:key name="booksByAuthor" match="book" use="author"/>
<xsl:template match="/">
<html>
<body>
<h2>Books Grouped by Author</h2>
<xsl:for-each
select="library/book[generate-id() = generate-id(key('booksByAuthor', author)[1])]">
<!-- 2. Group heading: the author -->
<h3><xsl:value-of select="author"/></h3>
<ul>
<!-- 3. Get all books by this author -->
<xsl:for-each select="key('booksByAuthor', author)">
<li><xsl:value-of select="title"/></li>
</xsl:for-each>
</ul>
</xsl:for-each>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Output
<html>
<body>
<h2>Books Grouped by Author</h2>
<h3>Alice</h3>
<ul>
<li>XML Basics</li>
<li>Advanced XML</li>
</ul>
<h3>Bob</h3>
<ul>
<li>XSLT in Action</li>
<li>XPath Mastery</li>
</ul>
</body>
</html>
How it Works
-
xsl:key
creates an index mapping authors → their books. -
key('booksByAuthor', author)
retrieves all books for a given author. -
[generate-id() = generate-id(key('booksByAuthor', author)[1])]
ensures we only pick the first book of each author (so each group is processed once).