The XPath expressions you've seen so far—element names,
@
plus an attribute name, /
, comment(
)
, text( )
, and processing-instruction( )
—are all single
location steps. You can combine these with the
forward slash to move around the hierarchy from the
matched node to other nodes. Furthermore, you can use a period to
refer to the context node, a double period to refer to the parent
node, and a double forward slash to refer to descendants of the
context node. With the exception of //
, these are all similar to Unix shell
syntax for navigating a hierarchical filesystem.
Location steps can be combined with a forward slash
(/
) to make a compound location
path. Each step in the path is relative to the one that preceded it.
If the path begins with /
, then
the first step in the path is relative to the root node. Otherwise, it's relative to the context
node. For example, consider the XPath expression /people/person/name/first_name
. This
begins at the root node, then selects all people
element children of the root node,
then all person
element children
of those nodes, then all name
children of those nodes, and finally all first_name
children of those nodes.
Applied to Example 9-1, it
indicates these two elements:
<first_name>Alan</first_name> <first_name>Richard</first_name>
To indicate only the textual content of those two nodes, we
have to go one step further. The XPath expression /people/person/name/first_name/text( )
selects the strings "Alan" and "Richard" from Example 9-1.
These two XPath expressions both began with /
, so they're absolute location paths that start at the root.
Relative location paths can also count down from the context node.
For example, the XPath expression person/@id
selects the id
attributes of the person
child elements of the context
node.
A double forward slash (//
) selects from all descendants of the
context node, as well as the context node itself. At
the beginning of an XPath expression, it selects from all of the
nodes in the document. For example, the XPath expression //name
selects all name
elements in the document. The
expression //@id
selects all the
id
attributes of any element in
the document. The expression person//@id
selects all the id
attributes of any element contained in
the person
child elements of the
context node, as well as the id
attributes of the person
elements
themselves.
A double period (..
)
indicates the parent of the current node. For example, the XPath
expression //@id
identifies all
id
attributes in the document.
Therefore, //@id/..
identifies
all elements in the document that have id
attributes. The XPath expression
//middle_initial/../first_name
identifies all first_name
elements that are siblings of middle_initial
elements in the document.
Applied to Example 9-1,
this selects <first_name>Richard</first_name>
but not <first_name>Alan</first_name>
.
Finally, the single period (.
) indicates the context node. In XSLT
this is most commonly used when you need to take the value of the
currently matched node. For example, this template rule copies the
content of each comment in the input document to a span
element in the output
document:
<xsl:template match="comment( )"> <span class="comment"><xsl:value-of select="."></span> </xsl:template>
The . given as the value of the select
attribute of xsl:value-of
stands for the matched node.
This works equally well for element nodes, attribute nodes, and all
the other kinds of nodes. For example, this template rule matches
name
elements from the input
document and copies their value into strongly emphasized text in the
output document:
<xsl:template match="name"> <strong><xsl:value-of select="."></strong> </xsl:template>