XSLT 2.0 and XPath 2.0 Programmer's Reference, 4th Edition (581 page)

BOOK: XSLT 2.0 and XPath 2.0 Programmer's Reference, 4th Edition
6.18Mb size Format: txt, pdf, ePub

See Also

escape-uri-attributes
serialization option on page 938 in Chapter 15.

encode-for-uri()
on page 771

escape-html-uri()
on page 775

key

This function is available in XSLT only
.

The
key()
function is used to find the nodes with a given value for a named key. It is used in conjunction with the

element described on page 376 in Chapter 6.

For example, if there is a key definition:

 

then the expression
key(‘vreg’, ‘N498PAA’)
might return the single element

.

Changes in 2.0

The key value can now be of any type and is compared according to the rules for that type. The key definitions in

can also now specify a collation to be used for comparing strings.

An optional third argument has been added to identify the document to be searched.

Signature

Argument
Type
Meaning
name
xs:string
Specifies the name of the key. The value of the string must be a lexical
QName
that identifies a key declared using an

element in the stylesheet.
value
xs:anyAtomicType*
Specifies the required value of the key, in a way that depends on the type. See below.
top
(optional)
node()
Identifies the tree to be searched. If this argument is omitted, the document containing the context node is searched.
Result
node()*
The nodes with the required key values, returned without duplicates, and in document order
.

Effect

The first argument must take the form of a lexical
QName
, that is, an XML name optionally prefixed with a namespace prefix that corresponds to a namespace declaration that is in scope at the point in the stylesheet where the
key()
function is called. If there is no namespace prefix, the relevant namespace URI is null; the default namespace is not used. There must be an

element in the stylesheet with the same expanded QName, using the namespace URIs rather than prefixes in the comparison. If there is more than one

element with this name, they are all used: a node is considered to match the key if it matches any of the key definitions with this name.

The second argument is a sequence of atomic values (usually a single atomic value, but this is treated as a sequence of length one). If the value actually supplied in the function call includes nodes, the nodes are atomized to create a sequence of atomic values. The result of the
key()
function contains every node in the same document as the context node that has at least one key value that is equal to one of the values supplied in this sequence.

The key values can be of any type. The values of the keys as indexed using

will be compared with the keys supplied in the
key()
function, using the rules of the XPath
eq
operator without any special type conversion; this means, for example, that if the indexed value is the
xs:integer
value 23, it will not be retrieved by the call
key(‘k’, ‘23’)
, because the integer 23 and the string
‘23’
do not compare as equal. Untyped atomic values (values extracted from unvalidated nodes) are treated as strings and can only be compared with strings. If a collation is specified in the

declaration, it will be used when comparing strings; otherwise, the default collation will be used.

The optional
top
argument identifies the tree to be searched. The value can be any node, not necessarily a document node. The default value is the document node of the tree containing the context node. The function searches the subtree rooted at this node, so you can either search a whole document, or a subtree rooted at a particular element (this differs from the
id()
and
idref()
functions). A node will be selected by the function only if it has
top
as an ancestor-or-self node. When the third argument is omitted, it's an error if there is no context item, or if the context item isn't a node. It's also an error to search in a tree that doesn't have a document node as its root (this rule is for the convenience of implementors, to allow indexes to be maintained at the level of a document).

Usage and Examples

The
key()
function is provided to make associative access to nodes (finding the nodes given their content) more convenient and more efficient. Efficiency of course depends entirely on the implementation, but it is likely that most implementations will use some kind of index or hash-table data structure to make the
key()
function faster than the equivalent path expression using predicates to select the required value.

Another use for keys is that they provide an efficient way of grouping related nodes together. This usage is needed far less under XSLT 2.0, because of the introduction of the

instruction, but it is still worth your while to understand it.

We will examine these two ways of using keys in turn.

Using Keys to Find Nodes by Value

To locate the

elements having J. B. Priestley as the content of one of their

child elements, you could write:


However, it is probably more efficient, if this is done frequently in the stylesheet, to define the author name as a key.




The
key()
function normally locates elements in the same document as the context node. When you need to locate elements in a different document, you can identify this in the third argument, for example:


The key value is usually supplied as a string, or as an expression that returns a string. In XSLT 2.0 it can also be a value of another atomic type; for example, you can use a number or a date as a key. It does not have to be a single value; you can supply a sequence of strings (or numbers or dates, if that is how the key is defined), and the function will return all the nodes that match any one of the values.

Keys are particularly useful for following cross-references. If you supply the key value as a node, or a sequence of nodes, then the values held in those nodes will be used as the key values. The next example explores this in more detail.

Example: Using Keys as Cross-References

This example uses two source files: the principal source document is a file containing a list of books, and the secondary one (accessed using the
document()
function) contains biographies of authors. The author name held in the first file acts as a cross-reference to the author's biography in the second file, rather like a join in SQL.

Source

The principal source document is an abbreviated version of the
booklist.xml
file:



     The Young Visiters

     Daisy Ashford



     When We Were Very Young

     A. A. Milne



The secondary source document,
authors.xml
, reads like this. I've included only two authors to keep it short, but the
key()
function would really come into its own if there were hundreds of entries.



1852

1956

Alan Alexander Milne, educated at Westminster School and Trinity College Cambridge, became a prolific author of plays, novels, poetry, short stories, and essays, all of which have been overshadowed by his children's books. 



1881

1972

Daisy Ashford (Mrs George Norman) wrote 
The Young Visiters
, a small comic masterpiece, while still a young child in Lewes. It was found in a drawer in 1919 and sent to Chatto and Windus, who published it in the same year with an introduction by J. M. Barrie, who had first insisted on meeting the author in order to check that she was genuine. 
  

Stylesheet

The stylesheet is in the file
author-biogs.xsl
. It declares a key to match

elements by their
name
attribute. This is intended for use with the
authors.xml
file, though there is nothing in the key definition to say so.

Note the use of a global variable to reference the secondary source file. It would be possible to use the
document()
function each time the file is accessed, and any XSLT processor worthy of the name would actually read and parse the file only once, but using a variable in my view makes it easier to see what is going on.

The actual call on the
key()
function is in the path expression
$biogs/key(‘biog’, $name)
. The purpose of the first step,
$
biogs, is to switch the context node to the
authors.xml
document, because the
key()
function (when used with two arguments) always looks in the document containing the context node. The expression could equally have been written
key(‘biog’, name, $biogs)
.

 version=“2.0”

>




  

  

    

                

     

     Authors

     

                

        

        

                

        

                      select=“$biogs/key(‘biog’, $name)”/>

        


          

        


        


      

    

  



Output

The output obtained if you run this stylesheet with the subset of the
booklist.xml
file shown earlier is as follows.


   

      The Young Visiters

      Author

      Daisy Ashford

      

1881 - 1972


      

Daisy Ashford (Mrs George Norman) wrote The Young Visiters, a small comic masterpiece, while still a young child in Lewes. It was found in a drawer in 1919 and sent to Chatto and Windus, who published it in the same year with an introduction by J. M. Barrie, who had first insisted on meeting the author in order to check that she was genuine.


      When We Were Very Young

      Author

      A. A. Milne

      

1852 - 1956


      

Alan Alexander Milne, educated at Westminster School and Trinity College Cambridge, became a prolific author of plays, novels, poetry, short stories, and essays, all of which have been overshadowed by his children's books.




Other books

The Bomber Dog by Megan Rix
Intel Wars by Matthew M. Aid
Love Blind by C. Desir
Only a Kiss by Mary Balogh
Semi-Detached by Griff Rhys Jones
Fatal Trust by Diana Miller
A Fine Passion by Stephanie Laurens