Grouping Nodes

When grouping nodes, we sort things to get them into a certain order, then we group all items that have the same value for the sort key (or keys). We’ll use xsl:sort for this grouping, then use variables or functions like key() or generate-id() to finish the job.

Our First Attempt

For our first example, we’ll take our list of addresses and group them. We’ll look for all unique values of the <zip> element and list the addresses that match each one. What we’ll do is sort the list by Zip Code, then go through the list. If a given item doesn’t match the previous Zip Code, we’ll print out a heading; if it does match, we’ll just print out the address. Here’s our first attempt:

<?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text" indent="no"/> <xsl:variable name="newline"> <xsl:text> </xsl:text> </xsl:variable> <xsl:template match="/"> <xsl:text>Addresses sorted by Zip Code</xsl:text> <xsl:value-of select="$newline"/> <xsl:for-each select="addressbook/address"> <xsl:sort select="zip"/> <xsl:if test="zip!=preceding-sibling::address[1]/zip"> <xsl:value-of select="$newline"/> <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:value-of select="$newline"/> </xsl:if> <xsl:if test="name/title"> <xsl:value-of select="name/title"/> <xsl:text> </xsl:text> ...

Get XSLT now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.