start page | rating of books | rating of authors | reviews | copyrights

Book HomeXML in a NutshellSearch this book

22.3. Location Paths

Node-sets are returned by location-path expressions. Location paths consist of location steps. Each location step contains an axis and a node test separated by a double colon. That is, a location step looks like this:

axis::node test

The axis specifies in which direction from the context node the processor searches for nodes. The node test specifies which nodes along that axis are selected. These are some location steps with different axes and node tests:

child::set
descendant-or-self::node( )
ancestor-or-self::*
attribute::xlink:href

Each location step may be suffixed with one or more predicates enclosed in square brackets that further winnow the node-set. For example:

child::set[position( )=2]
descendant-or-self::node( )[.='Eunice']
ancestor-or-self::*[position( )=2][.="Celeste"]
attribute::xlink:href[starts-with('http')]

Each individual location step is itself a relative location path. The context node against which the relative location path is evaluated is established by some means external to XPath--for example, by the current matched node in an XSLT template.

Location steps can be combined by separating them with forward slashes. Each step in the resulting location path sets the context node (or nodes) for the next path in the step. For example:

ancestor-or-self::*/child::*[position( )=1]
child::document/child::set[position( )=2]/following-sibling::*
descendant::node( )[.='Eunice']/attribute::ID

An absolute location path is formed by prefixing a forward slash to a relative location path. This sets the context node for the first step in the location path to the root of the document. For example, these are all absolute location paths:

/descendant::ship/ancestor-or-self::*/child::*[position( )=1]
/child::document/child::set[position( )=2]/following-sibling::*
/descendant::node( )[.='Eunice']/attribute::ID

Multiple location paths can be combined with the union operator (|) to form an expression that selects a node-set containing all the nodes identified by any of the location paths. For example, this expression selects a node-set containing all the set children of the context node, all the vector descendants of the context node, all ancestor elements of the context node and the root node, and all attributes of the context node named href:

child::set | descendant::vector | ancestor::* | attribute::href

22.3.1. Abbreviated Syntax

An abbreviated syntax is available for particularly common location steps. This is the syntax allowed in XSLT match patterns. In this syntax, five axes may use this shorthand:

.
The context node

..
The parent node

name
The child element or elements with the specified name

//
All descendants of the context node, and the context node itself

@name
The attribute of the context node with the specified name

Using the abbreviated syntax, the previous examples can be rewritten in the following manner:

set
descendant-or-self::node( )
ancestor-or-self::*
@xlink:href
set[position( )=2]
descendant-or-self::node( )[.='Eunice']
ancestor-or-self::*[position( )=2][.="Celeste"]
@xlink:href[starts-with('http')]
ancestor-or-self::*/*[position( )=1]
document/set[position( )=2]/following-sibling::*
descendant::node( )[.='Eunice']/@ID
//ship/ancestor-or-self::*/*[position( )=1]
/document/set[position( )=2]/following-sibling::*
/descendant::node( )[.='Eunice']/@ID
set | .//vector | ancestor::* | @href

Not all location steps can be rewritten using the abbreviated syntax. In particular, only the child, self, attribute, descendant-or-self, and parent axes can be abbreviated. The remaining axes must be spelled out in full.

22.3.2. Axes

Each XPath location step moves along an axis from a context node. The context node is a particular root, element, attribute, comment, processing-instruction, namespace, or text node in the XML document. (In practice, it's almost always an element node or the root node.) The context node may be a node selected by the previous location step in the location path, or it may be determined by extra-XPath rules, such as which node is matched by an xsl:template element.

However the context node is determined, it has some relationship to every other node in the document. The various axes divide the document into different, overlapping sets, depending on their relationship to the context node. There are exactly 13 axes you can use in an XPath location step:

child
All children of the context node. Only root and element nodes have children. Attribute and namespace nodes are not children of any node, though they do have parent nodes.

descendant
All nodes contained inside the context node, that is, a child node, a child of a child node, a child of a child of a child node, and so on. Only root and element nodes have descendants. Like the child axis, the descendant axis never contains attribute or namespace nodes.

descendant-or-self
Any descendant of the context node or the context node itself. // is an abbreviation for /descendant-or-self::node( )/.

parent
The element or root node that immediately contains the context node. Only the root node does not have a parent node. .. is an abbreviation for parent::node( ).

ancestor
The root node and all element nodes that contain the context node. The root node itself has no ancestors.

ancestor-or-self
All ancestors of the context node, as well as the node itself.

following-sibling
All nodes that follow the end of the context node and have the same parent node. Attribute and namespace nodes do not have siblings.

preceding-sibling
All nodes that precede the start of the context node and have the same parent node. Attribute and namespace nodes do not have siblings.

following
All nodes that begin after the context node ends, except for attribute nodes and namespace nodes; that is, all nodes after the context node except descendants.

preceding
All nodes that end before the context node begins, except for attribute nodes and namespace nodes; that is, all nodes before the context node except ancestors.

attribute
All attributes of the context node; the axis is empty if the context node is not an element node. This axis does not contain xmlns and xmlns:prefix attributes. @name is an abbreviation for attribute::name.

namespace
All namespaces in scope (not merely declared) on the context node; this axis is empty if the context node is not an element node.

self
The context node itself. A single period (.) is an abbreviation for self::node.

22.3.3. Node Tests

Each location step has at least an axis and a node test. The node test further refines the nodes selected by the location step. In an unabbreviated location step, a double colon (::) separates the axis from the node test. There are seven kinds of node tests:

name
An XML name matches all elements with the same name. However, along the attribute axis it matches all attributes with the same name instead; along the namespace axis it matches all namespaces with that prefix. As usual, if the element or attribute name is prefixed, only the URI to which the prefix is mapped matters, not the prefix itself.

prefix:*
Along most axes, this node test matches all element nodes whose namespace URIs are the same as the namespace URI to which this prefix is mapped, regardless of name. However, along the attribute axis, this node test matches all attribute nodes whose namespace URIs are the same as the namespace URI to which this prefix is mapped.

comment( )
This includes all comment nodes.

text( )
This includes all text nodes. Each text node is a maximum contiguous run of text between other types of nodes.

processing-instruction( )
processing-instruction('target')
With no arguments, this node test selects all processing instructions. With a single string argument, it selects all processing instructions that have the specified target.

node( )
This node test selects all nodes, regardless of type: attribute, namespace, element, text, comment, processing instruction, and root.

*
This test normally selects all element nodes, regardless of name. However, if the axis is the attribute axis, then it selects all attribute nodes. If the axis is the namespace axis, then it selects all namespace nodes.



Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.