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.
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.
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.