<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/css" href="http://commons.oreilly.com/wiki/skins/common/feed.css?97"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
	<channel>
		<title>XPath and XPointer/XPath in Action - Revision history</title>
		<link>http://commons.oreilly.com/wiki/index.php?title=XPath_and_XPointer/XPath_in_Action&amp;action=history</link>
		<description>Revision history for this page on the wiki</description>
		<language>en</language>
		<generator>MediaWiki 1.11.0</generator>
		<lastBuildDate>Wed, 19 Jun 2013 17:53:01 GMT</lastBuildDate>
		<item>
			<title>Docbook2Wiki: Initial conversion from Docbook</title>
			<link>http://commons.oreilly.com/wiki/index.php?title=XPath_and_XPointer/XPath_in_Action&amp;diff=5169&amp;oldid=prev</link>
			<description>&lt;p&gt;Initial conversion from Docbook&lt;/p&gt;

			&lt;table style=&quot;background-color: white; color:black;&quot;&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;tr&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;←Older revision&lt;/td&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;Revision as of 09:53, 7 March 2008&lt;/td&gt;
			&lt;/tr&gt;
		&lt;/table&gt;</description>
			<pubDate>Fri, 07 Mar 2008 09:53:46 GMT</pubDate>			<dc:creator>Docbook2Wiki</dc:creator>			<comments>http://commons.oreilly.com/wiki/index.php/Talk:XPath_and_XPointer/XPath_in_Action</comments>		</item>
		<item>
			<title>Docbook2Wiki: Initial conversion from Docbook</title>
			<link>http://commons.oreilly.com/wiki/index.php?title=XPath_and_XPointer/XPath_in_Action&amp;diff=5108&amp;oldid=prev</link>
			<description>&lt;p&gt;Initial conversion from Docbook&lt;/p&gt;

			&lt;table style=&quot;background-color: white; color:black;&quot;&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;tr&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;←Older revision&lt;/td&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;Revision as of 09:50, 7 March 2008&lt;/td&gt;
			&lt;/tr&gt;
		&lt;/table&gt;</description>
			<pubDate>Fri, 07 Mar 2008 09:50:41 GMT</pubDate>			<dc:creator>Docbook2Wiki</dc:creator>			<comments>http://commons.oreilly.com/wiki/index.php/Talk:XPath_and_XPointer/XPath_in_Action</comments>		</item>
		<item>
			<title>Docbook2Wiki: Initial conversion from Docbook</title>
			<link>http://commons.oreilly.com/wiki/index.php?title=XPath_and_XPointer/XPath_in_Action&amp;diff=5047&amp;oldid=prev</link>
			<description>&lt;p&gt;Initial conversion from Docbook&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{{XPath and XPointer/TOC}}&lt;br /&gt;
Taken on its own terms, as a teaching tool, XPath might not seem to meet the test for a practical standard: it's useful only in the context of some ''other'' standard. How do you demonstrate something like XPath without requiring the novice to learn that other standard as well? Luckily, several tools have emerged to simplify this task. These tools allow you to enter and modify an XPath expression — typically, a full location path — returning to you in some highlighted form a selected portion of a target document. (The portion in question might or might not be contiguous, of course, depending on how exotic the location path is.) In this chapter, I'll demonstrate XPath using a tool called XPath Visualiser, developed by Dmitre Novatchev.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;tip&amp;quot;&amp;gt;&lt;br /&gt;
'''Tip'''&lt;br /&gt;
&lt;br /&gt;
XPath Visualiser can be downloaded from the VBXML site, at ''http://www.vbxml.com''.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== XPath Visualiser: Some Background ==&lt;br /&gt;
&lt;br /&gt;
XPath Visualiser runs under Microsoft Windows, from Windows 95 on up, and is built on top of the Microsoft MSXML XML/XSLT processor included with the Internet Explorer browser. This operating environment for the tool implies some advantages and disadvantages to its use.&lt;br /&gt;
&lt;br /&gt;
An important practical advantage of this tool is that the results are ''visual''. As we go through the examples in this chapter, you'll be able instantly to see the effects — subtle or grand — of changes in XPath expressions. (You don't even need to use Windows, let alone XPath Visualiser itself, because all these effects are captured in screen shots for you.) Trying to explain verbally what an XPath expression &amp;quot;does&amp;quot; is a convenient way to extend a book's length, but it's not simple, and it's prone to misinterpretation. (A picture of an XPath expression is worth a thousand words of description.)&lt;br /&gt;
&lt;br /&gt;
Next, because XPath Visualiser uses a current version of the MSXML processor, its &amp;quot;understanding&amp;quot; of the XPath Recommendation is complete. If an expression is legal under the terms of that standard, you can illustrate it with XPath Visualiser.&lt;br /&gt;
&lt;br /&gt;
Interestingly, though, a significant disadvantage of using XPath Visualiser is ''also'' that it's based on MSXML. That's because MSXML supports not only the current versions of XPath and XSLT, but also an early version of XSLT (called plain-old XSL). I described this early version in [[XPath and XPointer/Introducing XPath and XPointer|Chapter 1]] and [[XPath and XPointer/XPath Basics|Chapter 2]]. Among the differences in this &amp;quot;backward-compatible&amp;quot; XSL processor is that it included numerous Microsoft-only capabilities; for example, you could use their version of what became XPath to select a valid document's document type declaration. (Note that this isn't a problem with XPath Visualiser itself, which deals only with true-blue XPath; it may be something to consider if you're planning to use MSXML for other purposes of your own.)&lt;br /&gt;
&lt;br /&gt;
XPath Visualiser is not a &amp;quot;program&amp;quot; per se. It's a plain-old frames-based set of HTML documents and a customized version of Microsoft's default XSL(T) stylesheet, which work only when viewed through Internet Explorer Versions 5 and up. (More precisely, it works only with MSXML Versions 3 and up. Internet Explorer 5 and 5.5 do not come with MSXML 3, although you could download and install MSXML 3 to run under them. Internet Explorer 6 comes with the next version of MSXML, Version 4.) [[XPath and XPointer/XPath in Action#xpathpointer-CHP-5-FIG-1|Figure 5-1]] shows a portion of how the browser window appears when you first open this frameset.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;xpathpointer-CHP-5-FIG-1&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 5-1. Startup view of XPath Visualiser'''&lt;br /&gt;
&lt;br /&gt;
[[Image:XPath and XPointer_I_5_tt256.png|Startup view of XPath Visualiser]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I've suppressed all toolbars except the standard one, to give me as much screen real estate as possible for displaying actual documents. (I've also tweaked the XPath Visualiser default stylesheet; as distributed, the tool displays the document's contents against a pale-blue background, which reproduces poorly in grayscale screen shots.) As you can see, the upper frame includes a number of user-interface controls for specifying the document to be viewed and the location path to be tested or demonstrated. By default, the location path is:&lt;br /&gt;
&lt;br /&gt;
 //*&lt;br /&gt;
&lt;br /&gt;
which selects all element nodes in the loaded document. When you've loaded a document using the controls at the top of this frame and clicked on the Select Nodes button, the nodes your location path has selected are highlighted in any of various ways. (The buttons labeled Variables and Keys have to do with XSLT processing and will not be covered here.) The document itself appears in the bottom frame; its display is an enhanced version of the default MSXML/Internet Explorer view of XML documents, showing the document as an expandable/collapsible &amp;quot;tree&amp;quot; of nodes. Because there's no document loaded when you first fire up XPath Visualiser, the main document window initially displays the simple text &amp;quot;XML source document.&amp;quot; Once you load a document and specify a location path, the lower frame changes in a manner resembling [[XPath and XPointer/XPath in Action#xpathpointer-CHP-5-FIG-2|Figure 5-2]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;xpathpointer-CHP-5-FIG-2&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 5-2. A document loaded into XPath Visualiser'''&lt;br /&gt;
&lt;br /&gt;
[[Image:XPath and XPointer_I_5_tt258.png|A document loaded into XPath Visualiser]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The lower frame of the window in [[XPath and XPointer/XPath in Action#xpathpointer-CHP-5-FIG-2|Figure 5-2]] contains an XML document used in [[XPath and XPointer/Location Steps and Paths|Chapter 3]]. There are a couple important things to observe about this changed display. First, XPath Visualiser's interface includes a series of &amp;quot;VCR buttons&amp;quot; (the series of arrowheads beneath the location path in the top frame), which you can use to step through a selected node-set. These VCR buttons are labeled to indicate which node in the node-set is currently selected and how many nodes are in the node-set altogether (&amp;quot;0 of 22/22 matches,&amp;quot; in this case). Second, the node(s) selected by the location path in the top frame are highlighted in the lower frame. This highlighting appears in [[XPath and XPointer/XPath in Action#xpathpointer-CHP-5-FIG-2|Figure 5-2]] and throughout the rest of this chapter, as a bordered, pale gray background (In the case of elements, as you can see, only the start tags are highlighted.) Finally, note the small vertical black bars to the left of certain elements' start tags. On screen, these are simply shaded &amp;lt;tt&amp;gt;+&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt; signs, placed there to expand and collapse the tree of nodes descending from elements that have descendants. (As you can see, the &amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;price&amp;lt;/tt&amp;gt; elements' start tags don't have these black bars, since they don't have expandable/collapsible sub trees.)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;note&amp;quot;&amp;gt;&lt;br /&gt;
'''Note'''&lt;br /&gt;
&lt;br /&gt;
For the remainder of the screen shots in this chapter, I'll simply show portions of the lower frame, preceded by the location path in regular code-style font such as:&lt;br /&gt;
&lt;br /&gt;
 //elementname&lt;br /&gt;
&lt;br /&gt;
This will enable me to show larger portions of the document.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sample XML Document ==&lt;br /&gt;
&lt;br /&gt;
To keep a consistent base for all the example location paths in this chapter, I'll refer to the same XML source document. This document is short but contains at least one of every XPath node type:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;!-- Basic astrological data for T's and J's signs --&amp;gt;&lt;br /&gt;
&amp;lt;?xml-stylesheet type=&amp;quot;text/xsl&amp;quot; href=&amp;quot;astro.xsl&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;astro xmlns:xlink=&amp;quot;http://www.w3.org/1999/xlink&amp;quot;&amp;gt;&lt;br /&gt;
   &amp;lt;sign start-date=&amp;quot;12-22&amp;quot; end-date=&amp;quot;01-20&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;name type=&amp;quot;main&amp;quot;&amp;gt;Capricorn&amp;lt;/name&amp;gt;&lt;br /&gt;
      &amp;lt;name type=&amp;quot;alt&amp;quot;&amp;gt;The Sea-Goat&amp;lt;/name&amp;gt;&lt;br /&gt;
      &amp;lt;!-- capricorn.gif corresponds to Unicode 3.0 #x2651 --&amp;gt;&lt;br /&gt;
      &amp;lt;symbol xlink:type=&amp;quot;simple&amp;quot; xlink:href=&amp;quot;capricorn.gif&amp;quot;/&amp;gt;&lt;br /&gt;
      &amp;lt;ruling_planet&amp;gt;Saturn&amp;lt;/ruling_planet&amp;gt;&lt;br /&gt;
      &amp;lt;ruling_planet&amp;gt;Earth&amp;lt;/ruling_planet&amp;gt;&lt;br /&gt;
      &amp;lt;energy&amp;gt;Feminine&amp;lt;/energy&amp;gt;&lt;br /&gt;
      &amp;lt;quality&amp;gt;Cardinal&amp;lt;/quality&amp;gt;&lt;br /&gt;
      &amp;lt;anatomy&amp;gt;&lt;br /&gt;
         &amp;lt;part&amp;gt;Bones&amp;lt;/part&amp;gt;&lt;br /&gt;
         &amp;lt;part&amp;gt;Knees&amp;lt;/part&amp;gt;&lt;br /&gt;
      &amp;lt;/anatomy&amp;gt;&lt;br /&gt;
   &amp;lt;/sign&amp;gt;&lt;br /&gt;
   &amp;lt;sign start-date=&amp;quot;05-21&amp;quot; end-date=&amp;quot;06-22&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;name type=&amp;quot;main&amp;quot;&amp;gt;Gemini&amp;lt;/name&amp;gt;&lt;br /&gt;
      &amp;lt;name type=&amp;quot;alt&amp;quot;&amp;gt;The Twins&amp;lt;/name&amp;gt;&lt;br /&gt;
      &amp;lt;!-- gemini.gif corresponds to Unicode 3.0 #x264A --&amp;gt;&lt;br /&gt;
      &amp;lt;symbol xlink:type=&amp;quot;simple&amp;quot; xlink:href=&amp;quot;gemini.gif&amp;quot;/&amp;gt;&lt;br /&gt;
      &amp;lt;ruling_planet&amp;gt;Mercury&amp;lt;/ruling_planet&amp;gt;&lt;br /&gt;
      &amp;lt;element&amp;gt;Air&amp;lt;/element&amp;gt;&lt;br /&gt;
      &amp;lt;energy&amp;gt;Feminine&amp;lt;/energy&amp;gt;&lt;br /&gt;
      &amp;lt;quality&amp;gt;Mutable&amp;lt;/quality&amp;gt;&lt;br /&gt;
      &amp;lt;anatomy&amp;gt;&lt;br /&gt;
         &amp;lt;part&amp;gt;Hands&amp;lt;/part&amp;gt;&lt;br /&gt;
         &amp;lt;part&amp;gt;Arms&amp;lt;/part&amp;gt;&lt;br /&gt;
         &amp;lt;part&amp;gt;Shoulders&amp;lt;/part&amp;gt;&lt;br /&gt;
         &amp;lt;part&amp;gt;Lungs&amp;lt;/part&amp;gt;&lt;br /&gt;
      &amp;lt;/anatomy&amp;gt;&lt;br /&gt;
   &amp;lt;/sign&amp;gt;&lt;br /&gt;
&amp;lt;/astro&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The document in question describes elementary properties of two of the Western-style astrological signs, Capricorn and Gemini. When first loaded into XPath Visualiser with the default &amp;quot;all elements&amp;quot; location path selected, it appears as shown in [[XPath and XPointer/XPath in Action#xpathpointer-CHP-5-FIG-3|Figure 5-3]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;xpathpointer-CHP-5-FIG-3&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 5-3. Sample astrological document loaded into XPath Visualiser'''&lt;br /&gt;
&lt;br /&gt;
[[Image:XPath and XPointer_I_5_tt261.png|Sample astrological document loaded into XPath Visualiser]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== General to Specific, Common to Far-Out ==&lt;br /&gt;
&lt;br /&gt;
I'll start out with some fundamental location paths, such as those selecting elements of a particular name, and move on to some special cases (such as examples using axes and predicates). The chapter will include a number of bizarre location paths probably unlike any you'd actually use, but at least theoretically (if not practically!) legitimate. Along the way, I'll poke into XPath functions, numeric operators, and so on. Each screen shot of XPath Visualiser's lower frame is accompanied by a brief English-language description of what's depicted.&lt;br /&gt;
&lt;br /&gt;
(If you're feeling sufficiently adventurous, you might want to guess what the location paths select before looking at the corresponding screen shots.)&lt;br /&gt;
&lt;br /&gt;
=== The Node Test ===&lt;br /&gt;
&lt;br /&gt;
As a reminder, XPath is capable of locating the following seven ''types'' of nodes: root; element, attribute, comment, PI, namespace, and text. There's also a special &amp;lt;tt&amp;gt;node( )&amp;lt;/tt&amp;gt; &amp;quot;node test,&amp;quot; which locates nodes of ''any'' type along the selected axis. I'll cover the attribute and namespace node types in a moment, but for now, here's how XPath (via XPath Visualiser) selects on the other types.&lt;br /&gt;
&lt;br /&gt;
The simplest of these is, of course, the root node itself. The location path to the root node consists of a single slash:&lt;br /&gt;
&lt;br /&gt;
 /&lt;br /&gt;
&lt;br /&gt;
XPath Visualiser depicts the result as shown in [[XPath and XPointer/XPath in Action#xpathpointer-CHP-5-FIG-4|Figure 5-4]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;xpathpointer-CHP-5-FIG-4&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 5-4. &amp;quot;Locating&amp;quot; the root node'''&lt;br /&gt;
&lt;br /&gt;
[[Image:XPath and XPointer_I_5_tt263.png|&amp;quot;Locating&amp;quot; the root node]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;warning&amp;quot;&amp;gt;&lt;br /&gt;
'''Warning'''&lt;br /&gt;
&lt;br /&gt;
Actually, the first thing you see when selecting on the simple / location path is an error message; only after clearing this error message are you greeted by the above. XPath Visualiser seems not to know how to visually represent the root node — not that ''I'' know how to, either!&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Of course, as in [[XPath and XPointer/XPath in Action#xpathpointer-CHP-5-FIG-2|Figure 5-2]] and [[XPath and XPointer/XPath in Action#xpathpointer-CHP-5-FIG-3|Figure 5-3]], you've already seen the results of selecting all elements in the document. [[XPath and XPointer/XPath in Action#xpathpointer-CHP-5-FIG-5|Figure 5-5]] is based on a location path identifying ''specific'' elements: the &amp;lt;tt&amp;gt;part&amp;lt;/tt&amp;gt; elements, in this case:&lt;br /&gt;
&lt;br /&gt;
 //part&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;xpathpointer-CHP-5-FIG-5&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 5-5. Locating all elements with the same name'''&lt;br /&gt;
&lt;br /&gt;
[[Image:XPath and XPointer_I_5_tt265.png|Locating all elements with the same name]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice how the highlighting has shifted; only those element nodes whose names are &amp;quot;part&amp;quot; are now selected. The sample document contains three comments. To select them, use the following (the results are as shown in [[XPath and XPointer/XPath in Action#xpathpointer-CHP-5-FIG-6|Figure 5-6]]):&lt;br /&gt;
&lt;br /&gt;
 //comment(  )&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;xpathpointer-CHP-5-FIG-6&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 5-6. Locating all comments'''&lt;br /&gt;
&lt;br /&gt;
[[Image:XPath and XPointer_I_5_tt267.png|Locating all comments]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There's only one PI in the sample document, which is the &amp;lt;tt&amp;gt;xml-stylesheet&amp;lt;/tt&amp;gt; PI in the document's prolog. You can select it using either of the following two location paths. In either case, the result is the same, as shown in [[XPath and XPointer/XPath in Action#xpathpointer-CHP-5-FIG-7|Figure 5-7]].&lt;br /&gt;
&lt;br /&gt;
 //processing-instruction(  )&lt;br /&gt;
 //processing-instruction(&amp;quot;xml-stylesheet&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;xpathpointer-CHP-5-FIG-7&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 5-7. Locating a PI'''&lt;br /&gt;
&lt;br /&gt;
[[Image:XPath and XPointer_I_5_tt269.png|Locating a PI]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;sidebar&amp;quot;&amp;gt;&lt;br /&gt;
'''Path Efficiency'''&lt;br /&gt;
&lt;br /&gt;
It might pay to heed the relative efficiency of one location path over another. While starting off a location path with the &amp;lt;tt&amp;gt;//&amp;lt;/tt&amp;gt; shortcut certainly ''works'', it forces the processor to navigate through the entire document tree even though the PI we're after is right there in the prolog. Thus, it'd be a much better use of processor resources to replace the double slash with a single one, as in these two examples:&lt;br /&gt;
&lt;br /&gt;
 /processing-instruction(  )&lt;br /&gt;
&lt;br /&gt;
 /processing-instruction(&amp;quot;xml-stylesheet&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Of course, if what you're really after is either all PIs in the document, or all &amp;lt;tt&amp;gt;xml-stylesheet&amp;lt;/tt&amp;gt; PIs, the double slashes do just that.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To select all text nodes, use:&lt;br /&gt;
&lt;br /&gt;
 //text(  )&lt;br /&gt;
&lt;br /&gt;
This isolates all text nodes in the document; see [[XPath and XPointer/XPath in Action#xpathpointer-CHP-5-FIG-8|Figure 5-8]] for XPath Visualiser's depiction.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;xpathpointer-CHP-5-FIG-8&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 5-8. Locating text nodes'''&lt;br /&gt;
&lt;br /&gt;
[[Image:XPath and XPointer_I_5_tt273.png|Locating text nodes]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, to select all element, comment, PI, and text nodes in a single step, use the &amp;lt;tt&amp;gt;node( )&amp;lt;/tt&amp;gt; special node type:&lt;br /&gt;
&lt;br /&gt;
 //node(  )&lt;br /&gt;
&lt;br /&gt;
See [[XPath and XPointer/XPath in Action#xpathpointer-CHP-5-FIG-9|Figure 5-9]] for the result.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;xpathpointer-CHP-5-FIG-9&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 5-9. Locating all elements, comments, PIs, and text nodes'''&lt;br /&gt;
&lt;br /&gt;
[[Image:XPath and XPointer_I_5_tt275.png|Locating all elements, comments, PIs, and text nodes]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
One interesting note about these results is that — as discussed in [[XPath and XPointer/Location Steps and Paths|Chapter 3]] — neither attribute nor namespace nodes are &amp;quot;visible&amp;quot; (or highlighted in [[XPath and XPointer/XPath in Action#xpathpointer-CHP-5-FIG-9|Figure 5-9]]) along the default &amp;lt;tt&amp;gt;child&amp;lt;/tt&amp;gt;:: axis. To access either, you must employ the &amp;lt;tt&amp;gt;attribute&amp;lt;/tt&amp;gt;:: or &amp;lt;tt&amp;gt;namespace&amp;lt;/tt&amp;gt;:: axis, respectively. For instance, either of the following works to select all attributes in the sample document:&lt;br /&gt;
&lt;br /&gt;
 //attribute::*&lt;br /&gt;
 //@*&lt;br /&gt;
&lt;br /&gt;
As you can see in [[XPath and XPointer/XPath in Action#xpathpointer-CHP-5-FIG-10|Figure 5-10]], XPath Visualiser selects the attributes as complete name-value pairs.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;xpathpointer-CHP-5-FIG-10&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 5-10. Locating attribute nodes'''&lt;br /&gt;
&lt;br /&gt;
[[Image:XPath and XPointer_I_5_tt277.png|Locating attribute nodes]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Namespace nodes are a special case, in XPath Visualiser as in most other contexts. As the README file accompanying the utility says:&lt;br /&gt;
&lt;br /&gt;
This tool will not display selected nodes that were not explicitly specified in the text of the xml source document. Most notably this is true for (propagated) namespace nodes . . . .However, the containing nodes are still [highlighted].&lt;br /&gt;
&lt;br /&gt;
That is for namespace nodes, XPath Visualiser does not highlight ''all'' elements within scope of the element declaring a given namespace, but only the declaration within the declaring element itself. For instance, this location path:&lt;br /&gt;
&lt;br /&gt;
 //namespace::xlink&lt;br /&gt;
&lt;br /&gt;
results in a display like [[XPath and XPointer/XPath in Action#xpathpointer-CHP-5-FIG-11|Figure 5-11]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;xpathpointer-CHP-5-FIG-11&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 5-11. Locating namespace nodes'''&lt;br /&gt;
&lt;br /&gt;
[[Image:XPath and XPointer_I_5_tt279.png|Locating namespace nodes]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In [[XPath and XPointer/XPath in Action#xpathpointer-CHP-5-FIG-11|Figure 5-11]], I've shown the &amp;quot;X of Y/Z matches&amp;quot; information in the upper frame. For other node types, the Y value in this phrase equals the Z. For namespace nodes, though, XPath Visualiser sets Y equal to the number of namespace-declaring elements matching the location path and Z equal to the number of elements within scope of the selected namespace declarations. If you refer back to the full code listing, you will see that (as [[XPath and XPointer/XPath in Action#xpathpointer-CHP-5-FIG-11|Figure 5-11]] shows) there are 26 elements, including the &amp;lt;tt&amp;gt;astro&amp;lt;/tt&amp;gt; element itself, within scope of the &amp;lt;tt&amp;gt;astro&amp;lt;/tt&amp;gt; element's declaration of the &amp;lt;tt&amp;gt;xlink&amp;lt;/tt&amp;gt; namespace.&lt;br /&gt;
&lt;br /&gt;
(Remember, by the way, the built-in namespace associated with all XML documents, the one bound to the &amp;lt;tt&amp;gt;xml&amp;lt;/tt&amp;gt;: prefix. If you change the above location path to:&lt;br /&gt;
&lt;br /&gt;
 //namespace::*&lt;br /&gt;
&lt;br /&gt;
XPath Visualiser changes the &amp;quot;Z&amp;quot; in &amp;quot;X of Y/Z&amp;quot; to ''52'' — that is, 26 namespace nodes for the &amp;lt;tt&amp;gt;xlink&amp;lt;/tt&amp;gt; namespace and 26 for the &amp;lt;tt&amp;gt;xml&amp;lt;/tt&amp;gt; namespace.)&lt;br /&gt;
&lt;br /&gt;
Finally, to select a document's entire contents, you'd use a compound location path:&lt;br /&gt;
&lt;br /&gt;
 //node(  ) | //@* | //namespace::*&lt;br /&gt;
&lt;br /&gt;
[[XPath and XPointer/XPath in Action#xpathpointer-CHP-5-FIG-12|Figure 5-12]] depicts the result.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;xpathpointer-CHP-5-FIG-12&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 5-12. Locating all nodes in a document'''&lt;br /&gt;
&lt;br /&gt;
[[Image:XPath and XPointer_I_5_tt282.png|Locating all nodes in a document]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Axes ===&lt;br /&gt;
&lt;br /&gt;
Previous examples have already demonstrated some of the simpler axes, that is, the &amp;lt;tt&amp;gt;child&amp;lt;/tt&amp;gt;::, &amp;lt;tt&amp;gt;attribute&amp;lt;/tt&amp;gt;::, and &amp;lt;tt&amp;gt;namespace&amp;lt;/tt&amp;gt;:: axes. (Many of the previous examples also demonstrated, without explicit comment, the use of the &amp;lt;tt&amp;gt;descendant-or-self::&amp;lt;/tt&amp;gt; axis, as abbreviated &amp;lt;tt&amp;gt;//&amp;lt;/tt&amp;gt;.) Let's take a look at some of the other axes now. Note that to use many of these other &amp;quot;family relationships,&amp;quot; we'll typically use one or more location steps to navigate to some particular node-set in the document ''followed by'' a location step, which &amp;quot;turns the viewpoint&amp;quot; along the axis in question.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;parent&amp;lt;/tt&amp;gt;:: axis, usually abbreviated .., looks &amp;quot;up&amp;quot; from the context node one level in the document's tree of nodes. A location path like:&lt;br /&gt;
&lt;br /&gt;
 //part/parent::*&lt;br /&gt;
&lt;br /&gt;
locates all parent elements of any elements named &amp;quot;part&amp;quot; — in the case of our sample document, as shown in [[XPath and XPointer/XPath in Action#xpathpointer-CHP-5-FIG-13|Figure 5-13]], the two &amp;lt;tt&amp;gt;anatomy&amp;lt;/tt&amp;gt; elements.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;xpathpointer-CHP-5-FIG-13&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 5-13. Locating the parents of any part elements'''&lt;br /&gt;
&lt;br /&gt;
[[Image:XPath and XPointer_I_5_tt284.png|Locating the parents of any part elements]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The parent of an attribute, comment, text node, or PI is the element that contains it (or, for comments and PIs in the document prolog, the root node). So:&lt;br /&gt;
&lt;br /&gt;
 //comment(  )/../@*&lt;br /&gt;
&lt;br /&gt;
(as you can see in [[XPath and XPointer/XPath in Action#xpathpointer-CHP-5-FIG-14|Figure 5-14]]) selects all attributes of all elements that are parents of (that is, that contain) any comment nodes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;xpathpointer-CHP-5-FIG-14&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 5-14. Using the parent:: axis to locate attributes of a comment's parent element'''&lt;br /&gt;
&lt;br /&gt;
[[Image:XPath and XPointer_I_5_tt286.png|Using the parent:: axis to locate attributes of a comment's parent element]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An important concept this screen shot illustrates is that although a full location path may contain references to many nodes at many levels of the document tree, ''only the final location step'' in the path identifies the nodes that will actually be selected. Here, neither the comment nodes nor their parents are highlighted by XPath Visualiser. As the final location step in the path indicates, only the attributes of those parents are ultimately selected.&lt;br /&gt;
&lt;br /&gt;
XPath does not define a simple &amp;lt;tt&amp;gt;sibling&amp;lt;/tt&amp;gt;:: axis; to get all siblings of a given node, you must use the &amp;lt;tt&amp;gt;preceding-sibling&amp;lt;/tt&amp;gt;:: and &amp;lt;tt&amp;gt;following-sibling&amp;lt;/tt&amp;gt;:: axes together. Something like this (note that this is a single compound location path wrapped over two lines):&lt;br /&gt;
&lt;br /&gt;
 //processing-instruction(&amp;quot;xml-stylesheet&amp;quot;)/preceding-sibling::node(  ) |&lt;br /&gt;
 //processing-instruction(&amp;quot;xml-stylesheet&amp;quot;)/following-sibling::node(  )&lt;br /&gt;
&lt;br /&gt;
This selects the siblings of the &amp;lt;tt&amp;gt;xml-stylesheet&amp;lt;/tt&amp;gt; PI, as shown in [[XPath and XPointer/XPath in Action#xpathpointer-CHP-5-FIG-15|Figure 5-15]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;xpathpointer-CHP-5-FIG-15&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 5-15. Selecting all siblings of a PI in the prolog'''&lt;br /&gt;
&lt;br /&gt;
[[Image:XPath and XPointer_I_5_tt288.png|Selecting all siblings of a PI in the prolog]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As the &amp;lt;tt&amp;gt;xml-stylesheet&amp;lt;/tt&amp;gt; PI is located in this document's prolog, it has one preceding sibling (the opening comment) and one following (the document's root &amp;lt;tt&amp;gt;astro&amp;lt;/tt&amp;gt; element).&lt;br /&gt;
&lt;br /&gt;
As discussed in [[XPath and XPointer/Location Steps and Paths|Chapter 3]], the &amp;lt;tt&amp;gt;preceding&amp;lt;/tt&amp;gt;:: and &amp;lt;tt&amp;gt;following&amp;lt;/tt&amp;gt;:: axes locate nodes that terminate before or begin after (respectively) the full scope of a given node's markup. They differ from &amp;lt;tt&amp;gt;preceding-sibling&amp;lt;/tt&amp;gt;:: and &amp;lt;tt&amp;gt;following-sibling&amp;lt;/tt&amp;gt;:: in not requiring a &amp;quot;shared parent&amp;quot; condition. The following location path:&lt;br /&gt;
&lt;br /&gt;
 //quality[.=&amp;quot;Cardinal&amp;quot;]/following::*&lt;br /&gt;
&lt;br /&gt;
as you can see in [[XPath and XPointer/XPath in Action#xpathpointer-CHP-5-FIG-16|Figure 5-16]], selects not only that &amp;lt;tt&amp;gt;quality&amp;lt;/tt&amp;gt; element's &amp;lt;tt&amp;gt;anatomy&amp;lt;/tt&amp;gt; sibling, but also that &amp;lt;tt&amp;gt;anatomy&amp;lt;/tt&amp;gt; element's children ''and'' all the other elements that follow the close of the &amp;lt;tt&amp;gt;quality&amp;lt;/tt&amp;gt; element — even those otherwise unrelated (except distantly) to it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;xpathpointer-CHP-5-FIG-16&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 5-16. Locating elements along the following:: axis'''&lt;br /&gt;
&lt;br /&gt;
[[Image:XPath and XPointer_I_5_tt290.png|Locating elements along the following:: axis]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;ancestor&amp;lt;/tt&amp;gt;:: and &amp;lt;tt&amp;gt;descendant&amp;lt;/tt&amp;gt;:: axes, of course, restrict the view from a given node to the same branch of the family tree in an up or down direction, respectively. Thus:&lt;br /&gt;
&lt;br /&gt;
 //part[.=&amp;quot;Knees&amp;quot;]/ancestor::*&lt;br /&gt;
&lt;br /&gt;
locates (as shown in [[XPath and XPointer/XPath in Action#xpathpointer-CHP-5-FIG-17|Figure 5-17]]) the &amp;lt;tt&amp;gt;anatomy&amp;lt;/tt&amp;gt; parent of that &amp;lt;tt&amp;gt;part&amp;lt;/tt&amp;gt; element, the &amp;lt;tt&amp;gt;sign&amp;lt;/tt&amp;gt; parent of that &amp;lt;tt&amp;gt;anatomy&amp;lt;/tt&amp;gt; element, and the &amp;lt;tt&amp;gt;astro&amp;lt;/tt&amp;gt; parent of that &amp;lt;tt&amp;gt;sign&amp;lt;/tt&amp;gt; element. (It also locates the root node but, as explained earlier, XPath Visualiser has no way to &amp;quot;highlight&amp;quot; the root node.)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;xpathpointer-CHP-5-FIG-17&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 5-17. Locating an element's ancestors'''&lt;br /&gt;
&lt;br /&gt;
[[Image:XPath and XPointer_I_5_tt292.png|Locating an element's ancestors]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Adding the &amp;lt;tt&amp;gt;-or-self&amp;lt;/tt&amp;gt; qualifier to the &amp;lt;tt&amp;gt;ancestor&amp;lt;/tt&amp;gt;:: or &amp;lt;tt&amp;gt;descendant&amp;lt;/tt&amp;gt;:: axis, on the other hand, selects not only that chain of parents but also the context node itself. The location path:&lt;br /&gt;
&lt;br /&gt;
 //part[.=&amp;quot;Knees&amp;quot;]/ancestor-or-self::*&lt;br /&gt;
&lt;br /&gt;
thus adds to the node-set selected by the preceding example the indicated &amp;lt;tt&amp;gt;part&amp;lt;/tt&amp;gt; element itself. [[XPath and XPointer/XPath in Action#xpathpointer-CHP-5-FIG-18|Figure 5-18]] illustrates.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;xpathpointer-CHP-5-FIG-18&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 5-18. Adding an element to its ancestor node-set, using the ancestor-or-self:: axis'''&lt;br /&gt;
&lt;br /&gt;
[[Image:XPath and XPointer_I_5_tt294.png|Adding an element to its ancestor node-set, using the ancestor-or-self:: axis]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Predicates ===&lt;br /&gt;
&lt;br /&gt;
[[XPath and XPointer/Location Steps and Paths|Chapter 3]] noted that while the axis &amp;quot;turns the view&amp;quot; in a particular direction from the context node, to further refine the list of nodes to be selected from among all those visible in that direction you must use a predicate. For instance:&lt;br /&gt;
&lt;br /&gt;
 //name[@type=&amp;quot;alt&amp;quot;]&lt;br /&gt;
&lt;br /&gt;
selects only those &amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt; elements whose &amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt; attributes have the value &amp;lt;tt&amp;gt;alt&amp;lt;/tt&amp;gt;. As you can see from [[XPath and XPointer/XPath in Action#xpathpointer-CHP-5-FIG-19|Figure 5-19]], this prunes the node-set of all &amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt; elements in the document down to just two — the ones whose string-values are &amp;lt;tt&amp;gt;The Sea-Goat&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;The Twins&amp;lt;/tt&amp;gt; — and excludes those (string-values &amp;lt;tt&amp;gt;Capricorn&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;Gemini&amp;lt;/tt&amp;gt;) whose &amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt; attributes have some value other than &amp;lt;tt&amp;gt;alt&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;xpathpointer-CHP-5-FIG-19&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 5-19. Trimming a node-set using a predicate'''&lt;br /&gt;
&lt;br /&gt;
[[Image:XPath and XPointer_I_5_tt296.png|Trimming a node-set using a predicate]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While on the subject of selecting via attribute values, by the way, this might be a good moment to illustrate the different effects produced by two similar but not identical predicates. First, consider this location path:&lt;br /&gt;
&lt;br /&gt;
 //*[@type!=&amp;quot;alt&amp;quot;]&lt;br /&gt;
&lt;br /&gt;
[[XPath and XPointer/XPath in Action#xpathpointer-CHP-5-FIG-20|Figure 5-20]] shows how this selects all elements in the source document whose &amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt; attribute does ''not'' equal &amp;lt;tt&amp;gt;alt&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;xpathpointer-CHP-5-FIG-20&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 5-20. Selecting all elements with an attribute whose value does not meet a condition'''&lt;br /&gt;
&lt;br /&gt;
[[Image:XPath and XPointer_I_5_tt298.png|Selecting all elements with an attribute whose value does not meet a condition]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Only four elements have a &amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt; attribute, and of those only two do ''not'' have the indicated value.&lt;br /&gt;
&lt;br /&gt;
[[XPath and XPointer/XPath Functions and Numeric Operators|Chapter 4]], under the discussion of the &amp;lt;tt&amp;gt;not( )&amp;lt;/tt&amp;gt; function, described how in some cases it seemed &amp;quot;obviously&amp;quot; to but did not actually perform identically to the &amp;lt;tt&amp;gt;!=&amp;lt;/tt&amp;gt; &amp;quot;not equal to&amp;quot; operator. That is, the preceding location path behaves differently from the following:&lt;br /&gt;
&lt;br /&gt;
 //*[not(@type=&amp;quot;alt&amp;quot;)]&lt;br /&gt;
&lt;br /&gt;
As you can see from [[XPath and XPointer/XPath in Action#xpathpointer-CHP-5-FIG-21|Figure 5-21]], this location path selects all element nodes which do not have a &amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt; attribute whose value is &amp;lt;tt&amp;gt;alt&amp;lt;/tt&amp;gt; — including all element nodes with no type attribute at all. Quite a difference!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;xpathpointer-CHP-5-FIG-21&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 5-21. Selecting all elements lacking a particular attribute with a particular value'''&lt;br /&gt;
&lt;br /&gt;
[[Image:XPath and XPointer_I_5_tt300.png|Selecting all elements lacking a particular attribute with a particular value]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arguably the most common predicate test is one that selects nodes from among a candidate node-set based on their positions within that node-set. You can use the &amp;lt;tt&amp;gt;position( )&amp;lt;/tt&amp;gt; function for this test; when simply testing for a single specific position, you can use the literal position number (or an expression that evaluates to a number) as the predicate. Thus, the following two location paths are identical:&lt;br /&gt;
&lt;br /&gt;
 //*[position(  )=3]&lt;br /&gt;
 //*[3]&lt;br /&gt;
&lt;br /&gt;
Using the sample document as its source, XPath Visualiser displays the result shown in [[XPath and XPointer/XPath in Action#xpathpointer-CHP-5-FIG-22|Figure 5-22]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;xpathpointer-CHP-5-FIG-22&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 5-22. Locating nodes based on their positions'''&lt;br /&gt;
&lt;br /&gt;
[[Image:XPath and XPointer_I_5_tt302.png|Locating nodes based on their positions]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As you can see, the result is a little surprising. The location path doesn't select simply the third element in the document; it selects the third child element of every element in the document. (As long as the &amp;lt;tt&amp;gt;parent&amp;lt;/tt&amp;gt; element has at least three children, of course. Elements with fewer than three children have none of their children selected. The location path &amp;lt;tt&amp;gt;//*[3]&amp;lt;/tt&amp;gt; might be read as, &amp;quot;Locate all elements in the document whose position along the (default) &amp;lt;tt&amp;gt;child::&amp;lt;/tt&amp;gt; axis equals 3.&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Also remember that a node's position along a given axis depends on the axis's ''direction'', forward or reverse. In particular, the &amp;lt;tt&amp;gt;ancestor&amp;lt;/tt&amp;gt;::, &amp;lt;tt&amp;gt;ancestor-or-self&amp;lt;/tt&amp;gt;::, &amp;lt;tt&amp;gt;preceding&amp;lt;/tt&amp;gt;::, and &amp;lt;tt&amp;gt;preceding-sibling&amp;lt;/tt&amp;gt;:: axes are ''reverse'' axes. All others (except the special case &amp;lt;tt&amp;gt;self&amp;lt;/tt&amp;gt;:: axis, for obvious reasons) are forward axes. The position is counted starting at the context node and proceeding in the direction of the axis towards the beginning of the document (reverse axes) or the end of the document (forward axes). Consider this location path:&lt;br /&gt;
&lt;br /&gt;
 //quality[.=&amp;quot;Mutable&amp;quot;]/preceding-sibling::*[1]&lt;br /&gt;
&lt;br /&gt;
XPath Visualiser selects the first preceding sibling of the &amp;lt;tt&amp;gt;Mutable quality&amp;lt;/tt&amp;gt; element in reverse document order, as you can see in [[XPath and XPointer/XPath in Action#xpathpointer-CHP-5-FIG-23|Figure 5-23]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;xpathpointer-CHP-5-FIG-23&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 5-23. Node position on a reverse-direction axis'''&lt;br /&gt;
&lt;br /&gt;
[[Image:XPath and XPointer_I_5_tt304.png|Node position on a reverse-direction axis]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If all axes were in the forward direction only, the preceding location path would have located the first &amp;lt;tt&amp;gt;Gemini name&amp;lt;/tt&amp;gt; element — that is, the first preceding sibling in document order of the &amp;lt;tt&amp;gt;Mutable quality&amp;lt;/tt&amp;gt; element. If you want to get the first node in document order when using a reverse axis, don't use the absolute position 1 in the predicate; use the &amp;lt;tt&amp;gt;last( )&amp;lt;/tt&amp;gt; function, as here:&lt;br /&gt;
&lt;br /&gt;
 //quality[.=&amp;quot;Mutable&amp;quot;]/preceding-sibling::*[last(  )]&lt;br /&gt;
&lt;br /&gt;
Now XPath Visualiser (or any other XPath 1.0-compliant processor) will indeed select that first &amp;lt;tt&amp;gt;Gemini name&amp;lt;/tt&amp;gt; element, as shown in [[XPath and XPointer/XPath in Action#xpathpointer-CHP-5-FIG-24|Figure 5-24]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;xpathpointer-CHP-5-FIG-24&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 5-24. Using last( ) on a reverse-direction axis'''&lt;br /&gt;
&lt;br /&gt;
[[Image:XPath and XPointer_I_5_tt306.png|Using last(  ) on a reverse-direction axis]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Functions ===&lt;br /&gt;
&lt;br /&gt;
For the most part, as explained in [[XPath and XPointer/XPath Functions and Numeric Operators|Chapter 4]], XPath functions are useful primarily in the predicates of location steps. They serve to narrow the focus to particular nodes in a candidate node-set in ways that can't be tested directly, for example, by checking the nodes' string-values.&lt;br /&gt;
&lt;br /&gt;
Among the node-set functions, the most esoteric are probably those having to do with namespaces. Still, these can be useful in ways completely unapproachable by any other means. In our sample document, we've got both an &amp;lt;tt&amp;gt;href&amp;lt;/tt&amp;gt; pseudoattribute (on the &amp;lt;tt&amp;gt;xml-stylesheet&amp;lt;/tt&amp;gt; PI) and a couple of &amp;lt;tt&amp;gt;xlink:href&amp;lt;/tt&amp;gt; attributes (on the &amp;lt;tt&amp;gt;symbol&amp;lt;/tt&amp;gt; elements). Because the strings &amp;quot;href&amp;quot; and &amp;quot;xlink:href&amp;quot; are clearly not equal — and because a PI's pseudoattributes are invisible along the regular &amp;lt;tt&amp;gt;attribute&amp;lt;/tt&amp;gt;:: axis — it might seem impossible to construct a location path that locates all hyperlink references in the document (assuming all such references appear either in a PI or as values of &amp;lt;tt&amp;gt;xlink:href&amp;lt;/tt&amp;gt; attributes) with a compound location path such as:&lt;br /&gt;
&lt;br /&gt;
 //@*[local-name()=&amp;quot;href&amp;quot;]/.. | //processing-instruction(  )[contains(., &amp;quot;href&amp;quot;)]&lt;br /&gt;
&lt;br /&gt;
This location path, applied to our sample document, locates the nodes shown in [[XPath and XPointer/XPath in Action#xpathpointer-CHP-5-FIG-25|Figure 5-25]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;xpathpointer-CHP-5-FIG-25&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 5-25. Locating href pseudoattributes and xlink:href attributes with a single location path'''&lt;br /&gt;
&lt;br /&gt;
[[Image:XPath and XPointer_I_5_tt308.png|Locating href pseudoattributes and xlink:href attributes with a single location path]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note in [[XPath and XPointer/XPath in Action#xpathpointer-CHP-5-FIG-25|Figure 5-25]] that the &amp;lt;tt&amp;gt;local-name( )&amp;lt;/tt&amp;gt; function serves to strip the namespace prefix from the attributes associated with the &amp;lt;tt&amp;gt;xlink&amp;lt;/tt&amp;gt;: namespace. Testing for some value in the PI requires use of a string function, like &amp;lt;tt&amp;gt;contains( )&amp;lt;/tt&amp;gt; here, because everything except the PI's name itself is considered (in XPath terms) one big string-value.&lt;br /&gt;
&lt;br /&gt;
The Boolean XPath functions, &amp;lt;tt&amp;gt;boolean( )&amp;lt;/tt&amp;gt; can be used to explicitly test for the very existence of a node, especially relative to the context node. For instance:&lt;br /&gt;
&lt;br /&gt;
 //*[boolean(child::*)]&lt;br /&gt;
&lt;br /&gt;
selects all elements in the document that have any child elements at all. This can also be abbreviated, taking advantage of various defaults and shortcuts, to the more enigmatic form:&lt;br /&gt;
&lt;br /&gt;
 //*[*]&lt;br /&gt;
&lt;br /&gt;
In either case, the result of applying this location path to our sample document is as shown in [[XPath and XPointer/XPath in Action#xpathpointer-CHP-5-FIG-26|Figure 5-26]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;xpathpointer-CHP-5-FIG-26&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 5-26. Using boolean( ) to locate all elements that are parents of other elements'''&lt;br /&gt;
&lt;br /&gt;
[[Image:XPath and XPointer_I_5_tt311.png|Using boolean(  ) to locate all elements that are parents of other elements]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When you turn to XPath string functions, you really start to open up the doors to fine-tuned (sometimes almost bizarrely so) location paths. If for some reason you wanted to locate all elements whose string-values began with a capital &amp;quot;M&amp;quot; or ended with a lowercase &amp;quot;e,&amp;quot; you could use this location path:&lt;br /&gt;
&lt;br /&gt;
 //node()[starts-with(., &amp;quot;M&amp;quot;) or substring(., string-length(  ), 1)=&amp;quot;e&amp;quot;]&lt;br /&gt;
&lt;br /&gt;
(Note that because there's no &amp;lt;tt&amp;gt;ends-with( )&amp;lt;/tt&amp;gt; function available under XPath 1.0, we have to simulate its purpose using the &amp;lt;tt&amp;gt;substring( )&amp;lt;/tt&amp;gt; function, starting with position ''N'' in an ''N''-length string for a length of one character.)&lt;br /&gt;
&lt;br /&gt;
This location path, applied to our sample document, is processed by XPath Visualiser as shown in [[XPath and XPointer/XPath in Action#xpathpointer-CHP-5-FIG-27|Figure 5-27]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;xpathpointer-CHP-5-FIG-27&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 5-27. Using XPath string functions'''&lt;br /&gt;
&lt;br /&gt;
[[Image:XPath and XPointer_I_5_tt313.png|Using XPath string functions]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sublimely Ridiculous ===&lt;br /&gt;
&lt;br /&gt;
As I've said, it's nearly impossible to theorize a portion of an XML document's content that ''cannot'' be located with XPath. That said, even some straightforward English-language questions can be answered only by very complex, even bizarre, XPath location steps. And even when the questions can be answered simply, it's possible — if your inclinations run to the perverse — to come up with incredible convolutions of syntax. Here are a couple of examples.&lt;br /&gt;
&lt;br /&gt;
For starters, look back at the sample document of astrological data, particularly at the contents of the part elements (within the two anatomy elements). Note that for any given astrological sign, the text nodes contained by the part elements identify either singular or plural body parts. (Our sample document, as it happens, includes only plurals, such as Bones and Shoulders.) So let's start by asking this English-language question:&lt;br /&gt;
&lt;br /&gt;
What are the main names of all astrological signs with at least one plural &amp;lt;tt&amp;gt;part&amp;lt;/tt&amp;gt; element?&lt;br /&gt;
&lt;br /&gt;
The easiest way to build up a long XPath location path is step by step, confirming that each step along the way does what it needs to do. In this case, the place to start might be at the ''end'' of the question: which &amp;lt;tt&amp;gt;part&amp;lt;/tt&amp;gt; elements have plural text nodes? A location path to accomplish this might look something like this:&lt;br /&gt;
&lt;br /&gt;
 //part[substring(., string-length(  ),1)=&amp;quot;s&amp;quot;]&lt;br /&gt;
&lt;br /&gt;
That is: locate all &amp;lt;tt&amp;gt;part&amp;lt;/tt&amp;gt; descendants of the root node, substring the last character in each of their string-values, and select only those for which that substring equals &amp;quot;s.&amp;quot; (Of course, this would fail to locate any part element whose string-value is &amp;quot;Teeth.&amp;quot; This is not an issue given the two astrological signs in question but be aware of such little wrinkles in making assumptions about your own documents' contents.) Applied to our sample document, XPath Visualiser comes up with the selection shown in [[XPath and XPointer/XPath in Action#xpathpointer-CHP-5-FIG-28|Figure 5-28]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;xpathpointer-CHP-5-FIG-28&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 5-28. Locating all &amp;quot;plural body parts&amp;quot;'''&lt;br /&gt;
&lt;br /&gt;
[[Image:XPath and XPointer_I_5_tt315.png|Locating all &amp;quot;plural body parts&amp;quot;]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Working backwards through our English-language question and comparing it to the sample document structure, the next thing we're evidently seeking is the &amp;lt;tt&amp;gt;sign&amp;lt;/tt&amp;gt; element corresponding to any of the selected &amp;quot;plural body parts&amp;quot; located by the existing location path. As is usual with XPath, there are a number of ways to locate such a &amp;lt;tt&amp;gt;sign&amp;lt;/tt&amp;gt; element. One way would be to use the &amp;lt;tt&amp;gt;ancestor&amp;lt;/tt&amp;gt;:: axis, as here (additional location step boldfaced):&lt;br /&gt;
&lt;br /&gt;
 //part[substring(., string-length(.),1)=&amp;quot;s&amp;quot;]'''/ancestor::sign'''&lt;br /&gt;
             &lt;br /&gt;
&lt;br /&gt;
As [[XPath and XPointer/XPath in Action#xpathpointer-CHP-5-FIG-29|Figure 5-29]] illustrates, the location path now walks the selection back up the document tree to the corresponding &amp;lt;tt&amp;gt;sign&amp;lt;/tt&amp;gt; elements.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;xpathpointer-CHP-5-FIG-29&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 5-29. Locating the sign elements with &amp;quot;plural body parts&amp;quot;'''&lt;br /&gt;
&lt;br /&gt;
[[Image:XPath and XPointer_I_5_tt317.png|Locating the sign elements with &amp;quot;plural body parts&amp;quot;]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The English-language question now says we need to locate the &amp;quot;main names&amp;quot; of all these signs. In terms of the document's structure, this can be interpreted as &amp;quot;all child &amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt; element(s) of the selected &amp;lt;tt&amp;gt;sign&amp;lt;/tt&amp;gt; element(s) that have a &amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt; attribute whose value is &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;.&amp;quot; Now the location path looks as follows:&lt;br /&gt;
&lt;br /&gt;
 //part[substring(., string-length(.),1)=&amp;quot;s&amp;quot;]/ancestor::sign'''/name[@type=&amp;quot;main&amp;quot;]'''&lt;br /&gt;
             &lt;br /&gt;
&lt;br /&gt;
[[XPath and XPointer/XPath in Action#xpathpointer-CHP-5-FIG-30|Figure 5-30]] shows how this location path works in practice.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;xpathpointer-CHP-5-FIG-30&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 5-30. Locating the main name element for each sign with &amp;quot;plural body parts&amp;quot;'''&lt;br /&gt;
&lt;br /&gt;
[[Image:XPath and XPointer_I_5_tt319.png|Locating the main name element for each sign with &amp;quot;plural body parts&amp;quot;]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
One further refinement: as you can see from [[XPath and XPointer/XPath in Action#xpathpointer-CHP-5-FIG-30|Figure 5-30]], the location path as it stands locates the desired name element(s) (with their start tags highlighted by XPath Visualiser). If we really want to locate the main ''names'' of the selected signs, we need to locate not the elements themselves, but rather the text nodes that make up their string-values. So our full location path would be:&lt;br /&gt;
&lt;br /&gt;
 //part[substring(., string-length(.),1)=&amp;quot;s&amp;quot;]/ancestor::sign/name[@type=&amp;quot;main&amp;quot;]&lt;br /&gt;
 '''/text(  )'''&lt;br /&gt;
             &lt;br /&gt;
&lt;br /&gt;
(Note that this location path breaks across two lines here, but actually is a single line for XPath Visualiser's purposes; in XPath's own terms, breaking this expression across two lines like this is quite acceptable.)&lt;br /&gt;
&lt;br /&gt;
In [[XPath and XPointer/XPath in Action#xpathpointer-CHP-5-FIG-31|Figure 5-31]], as you can see, XPath Visualiser finally answers our original question. It locates that actual name for which we're looking.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;xpathpointer-CHP-5-FIG-31&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 5-31. Locating the true name of each sign with &amp;quot;plural body parts&amp;quot;'''&lt;br /&gt;
&lt;br /&gt;
[[Image:XPath and XPointer_I_5_tt321.png|Locating the true name of each sign with &amp;quot;plural body parts&amp;quot;]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
One more example, this one based on (perhaps quite unreasonable!) assumptions about the way this document (and any other in the same vocabulary) is structured: each &amp;lt;tt&amp;gt;symbol&amp;lt;/tt&amp;gt; element is immediately preceded by a comment identifying the Unicode 3.0 character corresponding to the image file for that sign's symbol. Also note that a sign may have one or more one or more body parts (Bones and Knees for Capricorn; Hands, Arms, Shoulders, and Lungs for Gemini). Given these assumptions, we might frame a question such as the following: one or more body parts (Bones and Knees for Capricorn; Hands, Arms, Shoulders, and Lungs for Gemini)&lt;br /&gt;
&lt;br /&gt;
What is the name of the image file ''and'' the Unicode character equivalent for the symbol of each sign with more than two body parts?&lt;br /&gt;
&lt;br /&gt;
As with the previous example, let's begin at the end of the question by locating all the signs with more than two body parts:&lt;br /&gt;
&lt;br /&gt;
 //sign[count(descendant::part) &amp;gt; 2]&lt;br /&gt;
&lt;br /&gt;
[[XPath and XPointer/XPath in Action#xpathpointer-CHP-5-FIG-32|Figure 5-32]] shows that this selects only one &amp;lt;tt&amp;gt;sign&amp;lt;/tt&amp;gt; element (Gemini).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;xpathpointer-CHP-5-FIG-32&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 5-32. Locating signs with more than two body parts'''&lt;br /&gt;
&lt;br /&gt;
[[Image:XPath and XPointer_I_5_tt323.png|Locating signs with more than two body parts]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
How to proceed next may seem a little complicated, thanks to the presence in our question of the word &amp;quot;and.&amp;quot; All it really means, though, is that we'll be constructing a compound location path. We can work on either the &amp;quot;image file&amp;quot; or the &amp;quot;Unicode character&amp;quot; subordinate location path first; however, because we're going for baroque (sorry) here, let's assume that we want to get to the Unicode character ''by way of'' the corresponding image. The image for this &amp;lt;tt&amp;gt;sign&amp;lt;/tt&amp;gt; element can be singled out thus:&lt;br /&gt;
&lt;br /&gt;
 //sign[count(descendant::part) &amp;gt; 2]'''/symbol/@xlink:href'''&lt;br /&gt;
             &lt;br /&gt;
&lt;br /&gt;
That is, from the selected &amp;lt;tt&amp;gt;sign&amp;lt;/tt&amp;gt;s, walk down to their &amp;lt;tt&amp;gt;symbol&amp;lt;/tt&amp;gt; children and then select each &amp;lt;tt&amp;gt;symbol&amp;lt;/tt&amp;gt;'s &amp;lt;tt&amp;gt;xlink:href&amp;lt;/tt&amp;gt; attribute. [[XPath and XPointer/XPath in Action#xpathpointer-CHP-5-FIG-33|Figure 5-33]] illustrates the result.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;xpathpointer-CHP-5-FIG-33&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 5-33. Locating the image file for the symbol of each sign with more than two body parts'''&lt;br /&gt;
&lt;br /&gt;
[[Image:XPath and XPointer_I_5_tt325.png|Locating the image file for the symbol of each sign with more than two body parts]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now we've got to add a second location path, joined to the first by the union (&amp;lt;tt&amp;gt;|&amp;lt;/tt&amp;gt;, vertical bar or pipe symbol). For this second location path, we're going to navigate down to the same point as the first, but then go back to the preceding comment node:&lt;br /&gt;
&lt;br /&gt;
 //sign[count(descendant::part) &amp;gt; 2]/symbol/@xlink:href '''| '''&lt;br /&gt;
                '''//sign[count(descendant::part) &amp;gt; 2]/symbol/@xlink:href/../preceding-sibling::comment(  )'''&lt;br /&gt;
             &lt;br /&gt;
&lt;br /&gt;
An important part of this second location path is the &amp;lt;tt&amp;gt;/&amp;lt;/tt&amp;gt;.. buried within it, which shifts the context for succeeding location steps back up the document tree from the &amp;lt;tt&amp;gt;xlink:href&amp;lt;/tt&amp;gt; attribute, to its parent &amp;lt;tt&amp;gt;symbol&amp;lt;/tt&amp;gt; element. If you omit this location step, the location path attempts to select all preceding siblings ''of the attribute itself'' — which is almost never what you want (in answering this question or any other: it always returns an empty node-set).&lt;br /&gt;
&lt;br /&gt;
As you can see in [[XPath and XPointer/XPath in Action#xpathpointer-CHP-5-FIG-34|Figure 5-34]], we've succeeded in locating all information in the document about the symbols of all signs with more than two body parts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;xpathpointer-CHP-5-FIG-34&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 5-34. Locating all Unicode and image-file representations of the symbols for all signs with more than two body parts'''&lt;br /&gt;
&lt;br /&gt;
[[Image:XPath and XPointer_I_5_tt327.png|Locating all Unicode and image-file representations of the&lt;br /&gt;
symbols for all signs with more than two body parts]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
By the way, although it doesn't matter for this particular sample document, note that the compound location path is susceptible to breaking — returning an incorrect result — in at least one case. If there's more than one comment that is a preceding sibling for a given &amp;lt;tt&amp;gt;symbol&amp;lt;/tt&amp;gt;, the location path will select them all. Thus, to make the location path more robust, you might consider adding a predicate to the final location step, like this:&lt;br /&gt;
&lt;br /&gt;
 /comment(  )'''[contains(.,&amp;quot;corresponds to Unicode 3.0&amp;quot;)]'''&lt;br /&gt;
             &lt;br /&gt;
&lt;br /&gt;
Again, adding this predicate has no effect in the case of this particular document. There are other built-in assumptions in the full location path that may or may not be true in other documents in the &amp;quot;astrology markup language.&amp;quot; For example, the location path takes it for granted that each &amp;lt;tt&amp;gt;symbol&amp;lt;/tt&amp;gt; element ''will'' have an &amp;lt;tt&amp;gt;xlink:href&amp;lt;/tt&amp;gt; attribute; to be even more bullet-proof, the path might choose to ignore &amp;lt;tt&amp;gt;symbol&amp;lt;/tt&amp;gt; elements without that attribute. This depends of course on your application's specific needs. Just remember that as a rule, if you don't cover the unexpected in your location paths, XPath won't cover it for you!&lt;/div&gt;</description>
			<pubDate>Fri, 07 Mar 2008 09:45:23 GMT</pubDate>			<dc:creator>Docbook2Wiki</dc:creator>			<comments>http://commons.oreilly.com/wiki/index.php/Talk:XPath_and_XPointer/XPath_in_Action</comments>		</item>
	</channel>
</rss>