Microsoft XML Core Services (MSXML) 5.0 for Microsoft Office - XSLT Developer's Guide

Grouping Data by Using generate-id()

As an alternative to the complex syntax necessary to examine each node in a key's node-set, you can take advantage of the generate-id() function's ability to uniquely identify a node.

Here's an excerpt from the template rule in lib_cat2.xsl that groups books by author's name. The complete file is in Grouping Data by Examining the Keyed Node-set.

<xsl:template match="catalog" mode="grp_author">
    <h2>Titles Grouped by Author</h2>
    <xsl:for-each select="book[generate-id() = generate-id(key('author_key', author)[1])]">
        <xsl:sort select="author"/>
        <h3><xsl:value-of select="author" /></h3>
        <xsl:for-each select="key('author_key', author)">
            <xsl:sort select="title"/>
...
        </xsl:for-each>
    </xsl:for-each>
</xsl:template>

Here, the predicate portion of the outer <xsl:for-each> element's select attribute translates as follows: Select a <book> element only if its generated ID equals that of the first <book> element in the node-set established by the author_key key. When such a <book> is found, the template rule instantiates a level-3 heading, displaying the value of the corresponding <author> element.

The inner <xsl:for-each> translates as follows: Select all <book> elements in the node-set established by the author_key key, sort the books by a given author by their titles, and so on.

Example

XML File (books.xml)

Use the Sample XML File (books.xml). Below the line <?xml version='1.0'?>, add the following line:

<?xml-stylesheet type="text/xsl" href="lib_cat2.xsl"?>

XSLT File (lib_cat2.xsl)

See the listing in Grouping Data by Examining the Keyed Node-set.

Formatted Output

A portion of the output is shown here.

See Also

Grouping Data by Examining the Keyed Node-set | generate-id Function

Forward-compatible processing is also used when extensions have been applied to the XSLT parser. The extension namespace must be specified in the <xsl:stylesheet> element, using the extension-element-prefixes (or xsl:extension-element-prefixes)with each extension prefix used by the parser separated by white space.