The Ground Cero Guide to XSL
Henrik Aasted Sorensen
<< Basic XSLTMore XSLT >>
6. Introducing XPath
XPath is a language made for locating nodes in XML-documents. It's not in itself a XML-language, but is rather used as part of other XML-technologies (XSL, XPointer, XML Schema, X Query and others). This introduction to XPath may be a bit biased towards its use in XSL.
An XPath-expression consists of three parts:
axis::nodetest[filter]
axis defines which nodes, relative to the current node, that should be part of the expression. The most common values for this are:
  • self - The current node.
  • child - All the children of the current node.
  • descendant - All nodes below the current node in the tree.
  • parent - The current node's parent.
  • ancestor - All nodes above the current node in the tree.
nodetest is a simple way of filtering the selected nodes with regard to either their name or their type. Possible values are:
  • name - Picks only nodes with the specified name. This was the nodetest used in the examples in the above section.
  • * - Picks any node.
  • text() - Picks only nodes containing text.
  • node() - Returns the node.
filter is used for fine-grained filtering of the selected nodes. A filter will usually be a boolean expression (ie. an expression that will evaluate to either true or false). Another possibility is that the expression evaluates into a number. This will be translated into making the expression true for the node with the index (relative to its parent) that matches the number.
A few functions are available for these expressions:
  • position() - Returns the index of the current node.
  • last() - Returns the index of the last node selected. The index of the first node is 1.
  • true() and false() - returns the boolean values true and false.
  • not(expr) - Returns the inverse of the boolean expression given as an argument.
I believe this calls for examples.
Imagine that the current node is addresses and that it has several children.
The following XPath-expression will select the first 5 persons in the address-book:
child::add:person[6 > position()]
An expression that will pick person number 4 from the address-book. This is also an example of a filter that is NOT a boolean expression.
child::add:person[4]
This expression selects all people who are listed with their e-mail-address in the address-book:
child::add:person/add:email/parent::node()
This expression will select all the co-workers in the address-book:
child::add:person/add:category[contains(text(),'co-worker')]/parent::node()
Notice how, after checking the category-tag, it's necessary to go back up one node to pick the person-nodes.
This one will print every second person in the book.
child::add:person[position() mod 2 = 0]
Any of these expressions can be put in the select-attribute of an <xsl:apply-templates> or a <xsl:variable>-tag. It's possible to link together several expressions by using a | as a seperator.
add:email | add:phone
This will match both email- and phone-nodes. Not all tags that utilize XPath will be able to use several expressions like that. <xsl:apply-template> is able to do it, <xsl:value-of> is not.
The contains()-function is one of several functions capable of working on strings. Other functions are:
  • substring(string, number1, number2) - Returns the substring of the string supplied as argument.
  • string-length(string) - Returns the length of a string.
  • normalize-space(string) - Returns a space with all leading and trailing whitespace stripped.
Notice that all the above functions return a new string, while the contains()-function returns boolean.
A number of less readable, but easier to type abbreviations have been made for the axes:
  • axis abbr.
  • child Empty. This means that the default is to choose the choose the children of the current node.
  • self .
  • parent ..
Computer-savvy people may notice the resemblance to filesystem-handling syntax.
Looking at these abbreviations, it's possible to change the co-worker-example above to:
add:person/add:category[contains(text(),'co-worker')]/..
<< Basic XSLTMore XSLT >>
Index