XSL reference documentation generated from the W3C Recommendation 16 November 1999
Keys provide a way to work with documents that contain an implicit
cross-reference structure. The ID, IDREF
and IDREFS attribute types in XML provide a mechanism to
allow XML documents to make their cross-reference explicit. XSLT
supports this through the XPath
ID attributes must be declared as such in the DTD. If an ID
attribute is declared as an ID attribute only in the external DTD
subset, then it will be recognized as an ID attribute only if the XML
processor reads the external DTD subset. However, XML does not require
XML processors to read the external DTD, and they may well choose not
to do so, especially if the document is declared
standalone="yes".
A document can contain only a single set of unique IDs. There cannot be separate independent sets of unique IDs.
The ID of an element can only be specified in an attribute; it cannot be specified by the content of the element, or by a child element.
An ID is constrained to be an XML name. For example, it cannot contain spaces.
An element can have at most one ID.
At most one element can have a particular ID.
Because of these limitations XML documents sometimes contain a cross-reference structure that is not explicitly declared by ID/IDREF/IDREFS attributes.
A key is a triple containing:
the node which has the key
the name of the key (an expanded-name)
the value of the key (a string)
A stylesheet declares a set of keys for each document using the
xsl:key element. When this set of keys contains a member
with node x, name y and value
z, we say that node x has a key with name
y and value z.
Thus, a key is a kind of generalized ID, which is not subject to the same limitations as an XML ID:
Keys are declared in the stylesheet using
xsl:key elements.
A key has a name as well as a value; each key name may be thought of as distinguishing a separate, independent space of identifiers.
The value of a named key for an element may be specified in any convenient place; for example, in an attribute, in a child element or in content. An XPath expression is used to specify where to find the value for a particular named key.
The value of a key can be an arbitrary string; it is not constrained to be a name.
There can be multiple keys in a document with the same node, same key name, but different key values.
There can be multiple keys in a document with the same key name, same key value, but different nodes.
<key>
name = qname
match = pattern
use = expression
Model: EMPTY
</key>
The xsl:key element is used to declare keys. The
name attribute specifies the name of the key. The value
of the name attribute is a QName, which is expanded as described
in qname. The match attribute is a xsl:key element gives
information about the keys of any node that matches the pattern
specified in the match attribute. The use attribute is
an xsl:key element such that:
x matches the pattern specified in the
match attribute of the xsl:key element;
the value of the name attribute of the
xsl:key element is equal to y;
and
when the expression specified in the use
attribute of the xsl:key element is evaluated with
x as the current node and with a node list containing
just x as the current node list resulting in an object
u, then either z is equal to the result of
converting u to a string as if by a call to the
Note also that there may be more than one xsl:key
element that matches a given node; all of the matching
xsl:key elements are used, even if they do not have the
same
It is an error for the value of either the use
attribute or the match attribute to contain a VariableReference.
The
For example, given a declaration
<xsl:key name="idkey" match="div" use="@id"/>
an expression key("idkey",@ref) will return the same
node-set as id(@ref), assuming that the only ID attribute
declared in the XML source document is:
<!ATTLIST div id ID #IMPLIED>
and that the ref attribute of the current node
contains no whitespace.
Suppose a document describing a function library uses a
prototype element to define functions
<prototype name="key" return-type="node-set"> <arg type="string"/> <arg type="object"/> </prototype>
and a function element to refer to function names
<function>key</function>
Then the stylesheet could generate hyperlinks between the references and definitions as follows:
<xsl:key name="func" match="prototype" use="@name"/>
<xsl:template match="function">
<b>
<a href="#{generate-id(key('func',.))}">
<xsl:apply-templates/>
</a>
</b>
</xsl:template>
<xsl:template match="prototype">
<p><a name="{generate-id()}">
<b>Function: </b>
...
</a></p>
</xsl:template>
The <bibref>XSLT</bibref>, and there is a
separate XML document bib.xml containing a bibliographic
database with entries in the form:
<entry name="XSLT">...</entry>
Then the stylesheet could use the following to transform the
bibref elements:
<xsl:key name="bib" match="entry" use="@name"/>
<xsl:template match="bibref">
<xsl:variable name="name" select="."/>
<xsl:for-each select="document('bib.xml')">
<xsl:apply-templates select="key('bib',$name)"/>
</xsl:for-each>
</xsl:template>