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.