XSLT Reference
xsl:key
Defines a named index for efficiently selecting nodes using the key() function in XSLT 1.0 and later.
<xsl:key name="name" match="pattern" use="expression"/>Description
xsl:key declares a named index that associates nodes matched by the match pattern with key values computed by the use expression. Once declared, the key() function retrieves nodes from this index in constant time regardless of document size, making it the preferred technique for cross-referencing nodes.
Keys are declared as top-level elements of the stylesheet. Multiple xsl:key declarations with the same name accumulate: a node is indexed under a key value if any of the declarations with that name assigns that value to it. This makes it straightforward to build multi-column indexes.
The use expression is evaluated with the matched node as the context node. If use returns a node-set, each node in the set contributes a separate key value. String values are compared after whitespace normalization using the default collation.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
name | QName | Yes | The name used to reference this key in the key() function. |
match | pattern | Yes | An XSLT pattern identifying which nodes are indexed by this key. |
use | expression | Yes | An XPath expression evaluated for each matched node to determine its key value(s). |
Return value
xsl:key is a declaration — it produces no output. It instructs the processor to build an index that is queried via the key() function.
Examples
Looking up products by category
Input XML:
<?xml version="1.0" encoding="UTF-8"?>
<catalog>
<product id="p1" category="electronics">Laptop</product>
<product id="p2" category="books">XPath Guide</product>
<product id="p3" category="electronics">Tablet</product>
<product id="p4" category="books">XSLT Cookbook</product>
</catalog>
Stylesheet:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:key name="by-category" match="product" use="@category"/>
<xsl:template match="/catalog">
<electronics>
<xsl:for-each select="key('by-category', 'electronics')">
<item><xsl:value-of select="."/></item>
</xsl:for-each>
</electronics>
</xsl:template>
</xsl:stylesheet>
Output:
<electronics>
<item>Laptop</item>
<item>Tablet</item>
</electronics>
Muenchian grouping by first letter
Input XML:
<?xml version="1.0" encoding="UTF-8"?>
<names>
<name>Alice</name>
<name>Bob</name>
<name>Anna</name>
<name>Brian</name>
</names>
Stylesheet:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:key name="by-letter" match="name" use="substring(., 1, 1)"/>
<xsl:template match="/names">
<groups>
<xsl:for-each select="name[generate-id() = generate-id(key('by-letter', substring(., 1, 1))[1])]">
<group letter="{substring(., 1, 1)}">
<xsl:for-each select="key('by-letter', substring(., 1, 1))">
<name><xsl:value-of select="."/></name>
</xsl:for-each>
</group>
</xsl:for-each>
</groups>
</xsl:template>
</xsl:stylesheet>
Output:
<groups>
<group letter="A">
<name>Alice</name>
<name>Anna</name>
</group>
<group letter="B">
<name>Bob</name>
<name>Brian</name>
</group>
</groups>
Notes
xsl:keymust appear as a top-level child ofxsl:stylesheetorxsl:transform.- The Muenchian grouping technique relies on
xsl:keycombined withgenerate-id()and is the standard XSLT 1.0 method for grouping nodes. - In XSLT 2.0 and later,
xsl:for-each-groupsupersedes Muenchian grouping for most use cases, butxsl:keyremains useful for random-access lookups. - Keys built from large documents are cached by the processor and reused across multiple
key()calls.