An Illustration of the XSLT Key Construct

The information below is an extract from Crane Softwrights Ltd.'s XSLT/XPath book Practical Transformation Using XSLT and XPath (ISBN 1-894049-06-3). The current edition can be obtained through the page. See that page for details regarding the free updates of all editions to customers of any edition.

Section 8-2: Content and Document Referencing Techniques (Page 242)

The stylesheet can identify key nodes of the source tree for subsequent fast access by the XSLT processor:

  • identifies all source tree nodes for each declared key for stylesheet manipulation with a simple name
  • builds lookup table of member items based on an equality test for the lookup value
  • e.g.: relate all employee records to the employee's respective manager's employee record matching each employee's ManagedBy sub-element content value with the corresponding employee record with the same value for its emp= attribute

The XSLT processor can optimize searching in the lookup table

  • all values are fixed after the source tree is processed
  • the processor can index the table for quick retrieval based on lookup value
  • faster return of selected nodes than traversing the axes using XPath expressions and predicates evaluated at the point of reference

Not all processors support <xsl:key>

Establishing a lookup table of key relationships in a declarative fashion
When indexing behavior similar to XML ID/IDREF attribute cross-referencing values is required by either attribute or element content, the stylesheet writer can define and reference key values reflecting the implicit cross-references:

  • keys have three aspects of definition in the <xsl:key> top-level instruction:
    • the namespace-qualified name of the key
      • name="name-of-key-table"
      • the collection of key nodes distinguished from other collections of key nodes
      • multiple declarations with the same name cumulatively build the members in the collection of that name
    • the nodes that have the key
      • match="identifying-pattern-of-nodes-in-key-table"
      • a XPath matching pattern expression
        • similar to count= attribute in <xsl:number/>
    • the lookup values of the keyed nodes
      • use="expression-evaluating-the-value-of-key-in-the-set"
      • an XPath selection expression
        • if relative, then evaluated relative to each keyed node
      • expression evaluated to a string
      • string values need not be unique
        • nodes with like values are ordered in document order
  • the index built for a key is somewhat dissimilar to ID/IDREF
    • key values in the set need not be unique
      • there can be multiple key nodes in a document with the same node, same key name, but different key values
      • there can be multiple key nodes in a document with the same key name, same key value, but different nodes
    • a key's value need not be parsed as an XML name token
      • a node relative to the key node can represent the key's value
      • a key's value can be the result of an arbitrary expression evaluated with the key node as the current node
    • a lookup value need not be present in the collection

Note that a variable reference cannot be used in either the match= or use= expressions outside of a predicate.

Using a key

  • returns that subset of key nodes whose indexed key value is equal to the given string lookup value
  • returns the union of the call to key() with the value of each of the nodes in the node set as a lookup value

Predicates can be applied to the returned node set

  • key('taxes', 'Canada')[1]
    • returns only the first node of all nodes in the 'taxes' key table whose lookup value is the string 'Canada'
    • like lookup values are returned in document order of the nodes indexed, thus, this returns the first such node in document order
  • key('taxes', 'Canada')[@type='federal'][1]
    • of all nodes returned by the key function, return only the first whose type= attribute is 'federal'

The following example illustrates how keys can be used to obtain the value of an employee's name indirectly from the value of an attribute (though another model might have the value in sub-element content) used to reference the employee information of a manager:


The following steps correspond to the diagram indicating how the value "John Smith" is obtained as the name of the manager of "Joe Green" indirectly through the emp= attribute of the <ManagedBy> element:

  1. the template rule for <ManagedBy> needs to calculate a value from another node based on an attribute value in emp= (in another model it could just as well be based on an element node's value rather than an attribute node's value)
  2. the target value calculation begins by first referencing the key named "people", using the first argument to the key() function, specifying which of the lookup key tables that were created by the XSLT processor based on values found in the source tree
  3. the key named "people" is declared in a top-level <xsl:key> element building a table of nodes matching the given node-set expression indicated with match= (all element nodes named "Employee")
  4. the use= attribute specifies the expression whose evaluated value, relative to each match= node, that is used for the lookup comparison value in the key table (the value of the first child element node named "SSN" relative to the element nodes named "Employee")
  5. the second argument to key() function indicates the node (emp= attribute) relative to the current node (ManagedBy element) whose value is used for the search comparison with the key values (the attribute node for emp=)
  6. the example indicates the string value "1234" is what is searched for among the key lookup values
  7. key() returns all key nodes (Employee elements) whose lookup value is the string equivalent of the expression value for what is being searched for (only one node in this example)
  8. the <xsl:value-of> is calculated by then evaluating the complete expression by obtaining the XPath expression (the child element node named "Name") relative to the returned set of key nodes (Employee elements), thus returning the resulting value (the string "John Smith")

Note that the evaluation of key('people','1234') would have produced the same result since the lookup value is the supplied string instead of an evaluated expression.

Crane logo

BOX 266,

+1 (613) 489-0999 (Voice)
+1 (613) 489-0995 (Fax)


Link traversal: This web site relies heavily on client-side redirection. If certain links do not work for you, please ensure you have this behaviour enabled in your browser.

Site navigation:

Small print: All use of this web site and all business conducted with Crane Softwrights Ltd. is subject to the legal disclaimers detailed at ... please contact us if you have any questions. All trademarks, servicemarks, registered trademarks, and registered servicemarks are the property of their respective owners.

Link legend: links that are marked with this dotted underline will open up a new browser window, otherwise the same browser window is used for the link target. 

Last changed: $Date: 2006/12/27 20:44:29 $(UTC) (Privacy policy)