Home
XSLT Processor
Website Editor
CGI XSLT Processor
The style and source
Global parameters
Stylesheets
Stylesheet elements
Functions
Files upload
Details
Characters model
Data types
Result tree fragments
Variables scope
Conflict resolution
The key function
The document function
Curly brackets in attributes
Extensions
Extension modules
XSL message handlers
XML tree class
XSLT key function

Xsltp.pl Perl XSLT processor initializes the key function when it encounters the first call of the key function. It is instantiated with respect to the root node of the current document. If the current document is changed the instantiated key function will store the nodes of the previous document. The match attribute value of the key function is either a pattern or a node-set expression (not only a pattern). The use attribute value of the XSLT key function is any expression. The algorithm works as follows. If the value of the match attribute is a pattern (or a relative path) it is first converted to absolute path expression (x->//x). The expression is evaluated to construct the node-set. The use attribute is evaluated for each node in the node-set. The obtained values are used as the keys. Notice that the XSLT key function is efficient only when you employ it repeatedly.

Examples. Replacement of the id function
<xsl:key name="id" match="*" use="@id"/>
Array of elements
<xsl:key name="array" match="name" use="position()"/>
key('array',2) is the second name element of the document. Index for words
<xsl:key name="index" match="name" use="contains(.,'word')"/> 
key('index', true()) is the node-set of name elements with string value containing the word "word". The following code is also legal,
<xsl:key name="name1" match="$x/someelement" use="some expression"/>
Here, $x (global variable) is eather the node-set or the result tree fragment. And even this code
<xsl:key name="name2" match="key('array',2)/someelement" use="some expression"/>
is allowed.

Usage example. Let we have a list of books, something like this
<books>
<book>
<title>...</title>
<author>...</author>
<author>...</author>
<author>...</author>
</book>
....
</books>,
and wish to have a list of publications of each author. The following key function solves the problem
<xsl:key name="books_of_author" match="book" use="author"/>
provided that we know a way how to create the distinct list of authors. Here it is
<xsl:template match="books">
<authors-list>
<xsl:for-each select="book/author [self::author!=../following-sibling::book/author]">
<author>
<name><xsl:value-of select="."/></name>
<xsl:for-each select="key('books_of_author',.)">
<book-title><xsl:value-of select="title"/></book-title>
</xsl:for-each>
</author>
</xsl:for-each>
</authors-list>
</xsl:template>

Remark. Since we cannot get keys of the key function in XSLT, the above code is not efficient. The distinct list of authors is created two times here. First time, when the key function is initialized (with sorting algorithm) and, second time, when the distinct list itself is constructed in the XSLT code (without sorting algorithm).
Copyright 2004 www.dopscripts.com