page 44
This template selects the context node, represented by a period. To complete our tour of very simple location paths, we can use the double period
..
to select the parent of the context node:
xsl:value-of select=..
All these XPath expressions have one thing in common: they dont use element names. As you might have noticed in our Hello World example, you can use element names to select
elements that have a particular name:
xsl:apply-templates select=greeting
In this example, we select all of the
greeting
elements in the current context and apply the appropriate template to each of them. Turning to our XML sonnet, we can create location
paths that specify more than one level in the document hierarchy:
xsl:apply-templates select=linesline
This example selects all
line
elements that are contained in any
lines
elements in the current context. If the current context doesnt have any
lines
elements, then this expression returns an empty node-set. If the current context has plenty of
lines
elements, but none of them contain any
line
elements, this expression also returns an empty node-set.
3.2.3 Relative and Absolute Expressions
The XPath specification talks about two kinds of XPath expressions, relative and absolute. Our previous example is a relative XPath expression because the nodes it specifies depend on
the current context. An absolute XPath expression begins with a slash , which tells the
XSLT processor to start at the root of the document, regardless of the current context. In other words, you can evaluate an absolute XPath expression from any context node you want,
and the results will be the same. Heres an absolute XPath expression:
xsl:apply-templates select=sonnetlinesline
The good thing about an absolute expression is that you dont have to worry about the context node. Another benefit is that it makes it easy for the XSLT processor to find all nodes that
match this expression: what weve said in this expression is that there must be a
sonnet
element at the root of the document, that element must contain at least one
lines
element, and that at least one of those
lines
elements must contain at least one
line
element. If any of those conditions fail, the XSLT processor can stop looking through the tree and return
an empty node-set. A possible disadvantage of using absolute XPath expressions is that it could make your
templates more difficult to reuse. Both of these templates process
line
elements, but the second one is more difficult to reuse:
xsl:template match=line ...
xsl:template xsl:template match=sonnetlinesline
... xsl:template
If the second template has wonderful code for processing
line
elements, but your document contains
line
elements that dont match the absolute XPath expression, you cant reuse that template. You should keep that in mind as you design your templates.
3.2.4 Selecting Things Besides Elements with Location Paths
Up until now, weve discussed XPath expressions that used either element names
sonnetlinesline
or special characters or
..
to select elements from an XML
page 45
document. Obviously, XML documents contain things other than elements; well talk about how to select those other things here.
3.2.4.1 Selecting attributes
To select an attribute, use the at-sign along with the attribute name. In our sample sonnet,
you can select the
type
attribute of the
sonnet
element with the XPath expression
sonnettype
. If the context node is the
sonnet
element itself, then the relative XPath expression
type
does the same thing.
3.2.4.2 Selecting the text of an element
To select the text of an element, use the XPath node test
text
. The XPath expression
sonnetauth:authorlast-nametext
selects the text of the
last-name
element in our example document. Be aware that the text of an element is the concatenation of all of its text
nodes. Thus, the XPath expression
sonnetauth:authortext
returns the following text:
ShakespeareWilliamBritish15641616
Thats probably not the output you want; if you want to provide spacing, line breaks, or other formatting, you need to use the
text
node test against all the child nodes individually.
3.2.4.3 Selecting comments, processing instructions, and namespace nodes
By this point, weve covered most of the things youre ever likely to do with an XPath expression. You can use a couple of other XPath node tests to describe parts of an XML
document. The
comment
and
processing-instruction
node tests allow you to select comments and processing instructions from the XML document. Going back to our sample
sonnet, the XPath expression
processing-instruction
returns the two processing instructions named
xml-stylesheet
and
cocoon-process
. The expression
sonnetcomment
returns the comment node that begins, Is there an official title for this sonnet? Processing comment nodes in this way can actually be useful. If youve entered comments
into an XML document, you can use the
comment
node test to display your comments only when you want. Heres an XSLT template you could use:
xsl:template match=comment span class=comment
pxsl:value-of select=.p span
xsl:template
Elsewhere in your stylesheet, you could define CSS attributes to print comments in a large, bold, purple font. To remove all comments from your output document, simply go to your
stylesheet and comment out any
xsl:apply-templates select=comment
statements. XPath has one other kind of node, the rarely used namespace node. To retrieve namespace
nodes, you have to use something called the namespace axis; well discuss axes soon. One note about namespace nodes, if you ever have to use them: When matching namespace nodes,
the namespace prefix isnt important. As an example, our sample sonnet used the
auth
namespace prefix, which maps to the value
http:www.authors.com
. If a stylesheet uses the namespace prefix
writers
to refer to the same URL, then the XPath expression
sonnetwriters::
would return the
auth:author
element. Even though the namespace prefixes are different, the URLs they refer to are the same.
Having said all that, the chances that youll ever need to use namespace nodes are pretty slim.