<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/css" href="http://commons.oreilly.com/wiki/skins/common/feed.css?97"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>http://commons.oreilly.com/wiki/index.php?title=XPath_and_XPointer/Location_Steps_and_Paths&amp;action=history&amp;feed=atom</id>
		<title>XPath and XPointer/Location Steps and Paths - Revision history</title>
		<link rel="self" type="application/atom+xml" href="http://commons.oreilly.com/wiki/index.php?title=XPath_and_XPointer/Location_Steps_and_Paths&amp;action=history&amp;feed=atom"/>
		<link rel="alternate" type="text/html" href="http://commons.oreilly.com/wiki/index.php?title=XPath_and_XPointer/Location_Steps_and_Paths&amp;action=history"/>
		<updated>2013-05-20T02:38:10Z</updated>
		<subtitle>Revision history for this page on the wiki</subtitle>
		<generator>MediaWiki 1.11.0</generator>

	<entry>
		<id>http://commons.oreilly.com/wiki/index.php?title=XPath_and_XPointer/Location_Steps_and_Paths&amp;diff=5167&amp;oldid=prev</id>
		<title>Docbook2Wiki: Initial conversion from Docbook</title>
		<link rel="alternate" type="text/html" href="http://commons.oreilly.com/wiki/index.php?title=XPath_and_XPointer/Location_Steps_and_Paths&amp;diff=5167&amp;oldid=prev"/>
				<updated>2008-03-07T09:53:46Z</updated>
		
		<summary type="html">&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;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 505:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 505:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;| &lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;| &lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;-&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt; &lt;del style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;!&lt;/del&gt;=&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt; &lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;&amp;amp;#33;&lt;/ins&gt;=&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;| Not equal to&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;| Not equal to&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;|-&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;|-&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;!-- diff cache key wikicontent:diff:version:1.11a:oldid:5106:newid:5167 --&gt;
&lt;/table&gt;</summary>
		<author><name>Docbook2Wiki</name></author>	</entry>

	<entry>
		<id>http://commons.oreilly.com/wiki/index.php?title=XPath_and_XPointer/Location_Steps_and_Paths&amp;diff=5106&amp;oldid=prev</id>
		<title>Docbook2Wiki: Initial conversion from Docbook</title>
		<link rel="alternate" type="text/html" href="http://commons.oreilly.com/wiki/index.php?title=XPath_and_XPointer/Location_Steps_and_Paths&amp;diff=5106&amp;oldid=prev"/>
				<updated>2008-03-07T09:50:41Z</updated>
		
		<summary type="html">&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;</summary>
		<author><name>Docbook2Wiki</name></author>	</entry>

	<entry>
		<id>http://commons.oreilly.com/wiki/index.php?title=XPath_and_XPointer/Location_Steps_and_Paths&amp;diff=5045&amp;oldid=prev</id>
		<title>Docbook2Wiki: Initial conversion from Docbook</title>
		<link rel="alternate" type="text/html" href="http://commons.oreilly.com/wiki/index.php?title=XPath_and_XPointer/Location_Steps_and_Paths&amp;diff=5045&amp;oldid=prev"/>
				<updated>2008-03-07T09:45:23Z</updated>
		
		<summary type="html">&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;
In [[XPath and XPointer/XPath Basics|Chapter 2]], I covered the kinds of content XPath is capable of locating: essentially, any content at all in an XML document. Now it's time to take a look at how exactly you locate it — a look, in short, at XPath syntax.&lt;br /&gt;
&lt;br /&gt;
== XPath Expressions ==&lt;br /&gt;
&lt;br /&gt;
As earlier chapters (notably [[XPath and XPointer/Introducing XPath and XPointer|Chapter 1]]) have explained, knowing XML's own syntax does not prepare you for knowing XPath syntax. Unlike the languages that make use of XPath, XPath itself is not an XML vocabulary. A given &amp;quot;XPath&amp;quot; doesn't contain all the characteristic left and right angle brackets, ampersands, and other hallmarks of XML syntax dear (or not) to your heart from your other XML work.&lt;br /&gt;
&lt;br /&gt;
Instead, units of XPath meaning, called ''expressions'', are typically used in attribute values. Thus you'll be creating and using XML code that uses these expressions in ways such as:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;xsl:value-of select=&amp;quot;'''expression'''&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;a xlink:href=&amp;quot;xpointer('''expression''')&amp;quot;&amp;gt;Table of Contents&amp;lt;/a&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sometimes, when you see the term ''XPath expression'', what's being referred to is simply a speck of meaning — a subatomic particle, as it were, that has a sort of abstract academic interest but little practical value by itself. This sort of expression is a string or numeric value. For instance, both of the following are valid XPath expressions in this limited sense:&lt;br /&gt;
&lt;br /&gt;
 &amp;quot;I should have been a pair of ragged claws&amp;quot;&lt;br /&gt;
 119.725&lt;br /&gt;
&lt;br /&gt;
In the real world of XPath, though, such literal expressions are pretty pointless. If you locate the literal string &amp;quot;I should have been a pair of ragged claws,&amp;quot; you simply locate that string — outside the context of an XML document or, for that matter, devoid of any context at all. XPath expressions are meant primarily to locate content ''in context''. The most familiar real-world analogy for the syntax to accomplish this is a computer's filesystem or a web server's directory structure.&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;
Although I probably sounded scornful just now of literal-valued XPath expressions, don't write them off. The ability to &amp;quot;find&amp;quot; a literal value (instead of a chunk of content in the source document) is actually quite useful. You'll see many examples later in this chapter, particularly in the section on the predicate portion of an XPath expression. There, you'll learn how to locate a particular node (represented by a location path) when its value equals, say, some particular literal value. There's no way to represent the righthand side of this equation other than with a literal XPath expression. The point is merely that locating the literal value itself is absurd.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The Filesystem Analogy ===&lt;br /&gt;
&lt;br /&gt;
In [[XPath and XPointer/XPath Basics|Chapter 2]], [[XPath and XPointer/XPath Basics#xpathpointer-CHP-2-FIG-1|Figure 2-1]] depicted the structure of a well-formed XML document. Although I didn't make the comparison explicit, you may have observed that [[XPath and XPointer/XPath Basics#xpathpointer-CHP-2-FIG-1|Figure 2-1]] could also represent a directory tree: there's a root directory, beneath which you find one or more subdirectories, and so on. Within any directory along the way you might find one or more files.&lt;br /&gt;
&lt;br /&gt;
The analogy between locating files and other resources on the one hand and XML-based content in a document on the other is not just abstract but explicit, codified in the syntax. An expression such as the following might be a perfectly legitimate XPath expression as well as a path to one or more files in a computer filesystem:&lt;br /&gt;
&lt;br /&gt;
 /root/dir1/dir1_1/file&lt;br /&gt;
&lt;br /&gt;
If you're dealing with a computer operating system or a web URI, this entire syntactic construct is called (among other things) a directory path; in XPath, it's known as a ''location path''.&lt;br /&gt;
&lt;br /&gt;
=== Points of Similarity, Points of Difference ===&lt;br /&gt;
&lt;br /&gt;
Before getting into the nuances of location paths in their own right, I want to make plain some of the ways in which they are both similar to and different from directory paths. First, the similarities:&lt;br /&gt;
&lt;br /&gt;
* Most obviously, the syntax is very similar. Each incremental move through the tree of directories or nodes is separated from others by a slash, &amp;lt;tt&amp;gt;/&amp;lt;/tt&amp;gt;.&lt;br /&gt;
* The most common way to move through the directory or node tree is down: start at the root, select one of its children, then one of that child's children, and so on, until finding the resource at the very end of the path.&lt;br /&gt;
* Both a directory path and a location path can begin with a slash, in which case they're referred to as absolute paths. They can also dive right in with the name of some subordinate resource, with no leading slash, and in this case, they're called relative paths. What they're relative to is &amp;quot;wherever you are&amp;quot; in the filesystem or document in question.&lt;br /&gt;
* A syntactically correct path is no guarantee that you'll find anything there. When navigating — or attempting to navigate — a directory path to a resource that doesn't exist, you get a &amp;quot;File does not exist&amp;quot; error message from the operating system, or an HTTP 404 message from the web server; an XPath expression that &amp;quot;locates&amp;quot; a nonexistent resource fails less egregiously, but fails nonetheless: it returns an empty node-set.&lt;br /&gt;
&lt;br /&gt;
And now the chief differences, neither of them obvious from the simple example already presented:&lt;br /&gt;
&lt;br /&gt;
* Within a filesystem, you can easily &amp;quot;move up&amp;quot; or &amp;quot;move down&amp;quot; the directory tree to related resources (directories or files) in the same branch of the directory tree. &amp;quot;Moving sideways&amp;quot; isn't so easily accomplished, though, especially if you need to &amp;quot;move sideways&amp;quot; to different branches of the tree and/or to other resources whose names share nothing in common. XPath, as you will see, is amazingly flexible in terms of its knowledge of a document's tree of nodes and the multiple relationships a given node has with others.&lt;br /&gt;
* While you can use wildcard characters such as &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;?&amp;lt;/tt&amp;gt; to locate files that share some common naming characteristics, you cannot locate files that share the same ''type'' if their names share nothing in common. For instance, it's become common to name text files with a filename extension of ''.txt''. Using this ad-hoc and totally unofficial &amp;quot;standard,&amp;quot; however, both fails to locate text files with some other extension and possibly locates some ''non''-text files as well. That is, the name is no absolute guarantee of the type. XPath, in contrast, can easily locate types of content in a given document, as well as content with specific names.&lt;br /&gt;
&lt;br /&gt;
== Location Paths ==&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Understanding&amp;quot; a location path and how to code it requires no great intellectual leap. If you know how to walk a filesystem directory tree, separating each level in the navigation from the others with slashes, you already grasp the rudiments of location paths. Still, you need to keep a few points in mind.&lt;br /&gt;
&lt;br /&gt;
=== The Importance of Context ===&lt;br /&gt;
&lt;br /&gt;
[[XPath and XPointer/XPath Basics|Chapter 2]] discussed context, particularly the notion that each node in a given node-set shares with all the others a context size, and has its own context position within that size — the &amp;quot;Node X of Y&amp;quot; notion.&lt;br /&gt;
&lt;br /&gt;
More subtly, using a multilevel location path imposes a successively finer sieve of context on each level in the path. Consider:&lt;br /&gt;
&lt;br /&gt;
 /customers/customer/invoice/item/quantity&lt;br /&gt;
&lt;br /&gt;
As you move to the right in this location path, you're not only &amp;quot;walking down&amp;quot; into the document's nether regions, you're also almost certainly excluding from consideration various portions of the document not of interest at the moment. That is, each level in the location path ''implicitly changes the context node'' in terms of which levels to the right will be evaluated. [[XPath and XPointer/Location Steps and Paths#xpathpointer-CHP-3-FIG-1|Figure 3-1]] illustrates this process.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;xpathpointer-CHP-3-FIG-1&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 3-1. Filtering content via successive steps in a location path'''&lt;br /&gt;
&lt;br /&gt;
[[Image:XPath and XPointer_I_3_tt58.png|Filtering content via successive steps in a location path]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The full location path can be decomposed into five ''location steps'', each separated from the others by slashes; each step narrows the view already established by those that preceded it. Step 1 limits the selection to the root &amp;lt;tt&amp;gt;customers&amp;lt;/tt&amp;gt; element, and step 2, to the &amp;lt;tt&amp;gt;customer&amp;lt;/tt&amp;gt; elements that are children of that root element.&lt;br /&gt;
&lt;br /&gt;
So far, there's been no filtering at all occurring; every element down to this level in this sample document is still visible. In step 3, though, something interesting happens: the location path selects the &amp;lt;tt&amp;gt;invoice&amp;lt;/tt&amp;gt; children of each &amp;lt;tt&amp;gt;customer&amp;lt;/tt&amp;gt; element. The first and second &amp;lt;tt&amp;gt;customer&amp;lt;/tt&amp;gt; elements have two and one such children, respectively; the third &amp;lt;tt&amp;gt;customer&amp;lt;/tt&amp;gt; element has no &amp;lt;tt&amp;gt;invoice&amp;lt;/tt&amp;gt; children, and as a result this &amp;lt;tt&amp;gt;customer&amp;lt;/tt&amp;gt; effectively drops out of consideration as a match for further location steps. For purposes of content retrieved by this location path, in other words, &amp;lt;tt&amp;gt;customer&amp;lt;/tt&amp;gt; #3 might as well not exist at all.&lt;br /&gt;
&lt;br /&gt;
The filtering continues in steps 4 and 5. For some reason — perhaps data entry in this document is not complete — the &amp;lt;tt&amp;gt;invoice&amp;lt;/tt&amp;gt; child of &amp;lt;tt&amp;gt;customer&amp;lt;/tt&amp;gt; #2 has no &amp;lt;tt&amp;gt;item&amp;lt;/tt&amp;gt; children and thus disappears from view in step 4. In the fifth and final step, the location path says that ultimately, only the &amp;lt;tt&amp;gt;quantity&amp;lt;/tt&amp;gt; children of each &amp;lt;tt&amp;gt;item&amp;lt;/tt&amp;gt; element are of interest, eliminating the &amp;lt;tt&amp;gt;price&amp;lt;/tt&amp;gt; children and selecting, in the end, only those &amp;lt;tt&amp;gt;quantity&amp;lt;/tt&amp;gt; elements descended from (&amp;quot;belonging to&amp;quot;) the first &amp;lt;tt&amp;gt;customer&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
What does this have to do with context? The point is that each succeeding location step does not stand in isolation: the full location path doesn't select ''all'' customer elements, ''all'' invoice elements, and so on. In fact, it selects only those nodes (elements, in this case) at the very end of the location path, and of those, only the nodes that have met all preceding conditions in the path.&lt;br /&gt;
&lt;br /&gt;
=== Absolute Versus Relative Location Paths ===&lt;br /&gt;
&lt;br /&gt;
As I've already mentioned, location paths — just like directory paths — can be either absolute or relative. An absolute location path begins with a slash, which effectively denotes the root node of the document. If the path starts with ''no'' leading slash, it's a relative path.&lt;br /&gt;
&lt;br /&gt;
Practically speaking, when you're using XPath in an XPointer context, you'll always use an absolute path except when locating content within the same document containing the XPointer.&lt;br /&gt;
&lt;br /&gt;
In an XSLT stylesheet, the situation's a little more complicated. A typical stylesheet consists of numerous so-called template rules (one &amp;lt;tt&amp;gt;xsl:template&amp;lt;/tt&amp;gt; element apiece), each of which matches (via a location path) some portion(s) of the source document.&amp;lt;ref&amp;gt;Actually, to say the template rule &amp;quot;matches content via a location path&amp;quot; isn't quite accurate. The value of an &amp;lt;tt&amp;gt;xsl:template&amp;lt;/tt&amp;gt; element's &amp;lt;tt&amp;gt;match&amp;lt;/tt&amp;gt; attribute is not, strictly speaking, a location path, but rather something called a &amp;quot;location path pattern&amp;quot; or &amp;quot;match pattern&amp;quot; — whose syntax is dictated not by XPath, but by the XSLT spec. There's also a practical difference, in that a match pattern doesn't really select something in the source document; it simply (as the term indicates) ''matches'' that something, for purposes of specifying how the template will behave when a match is found.&amp;lt;/ref&amp;gt; Within the template rule may be any number of XPath-based references to other portion(s) of the document, and these latter references are most commonly relative location paths — that is, relative to the context established by the containing template rule. For instance, a template rule might look something like this:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;xsl:template match=&amp;quot;'''/books'''&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;xsl:for-each select=&amp;quot;'''book/title'''&amp;quot;&amp;gt;&lt;br /&gt;
       &amp;lt;xsl:value-of select=&amp;quot;'''.'''&amp;quot;/&amp;gt;&lt;br /&gt;
    &amp;lt;/xsl:for-each&amp;gt;&lt;br /&gt;
 &amp;lt;/xsl:template&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The location path bound to the template rule's &amp;lt;tt&amp;gt;match&amp;lt;/tt&amp;gt; attribute is absolute, matching the root &amp;lt;tt&amp;gt;books&amp;lt;/tt&amp;gt; element. Within the template rule, however, the location path bound to the &amp;lt;tt&amp;gt;xsl:for-each&amp;lt;/tt&amp;gt; element's &amp;lt;tt&amp;gt;select&amp;lt;/tt&amp;gt; attribute is relative — as is the one bound to the &amp;lt;tt&amp;gt;xsl:value-of&amp;lt;/tt&amp;gt; element's &amp;lt;tt&amp;gt;select&amp;lt;/tt&amp;gt; attribute. The former &amp;lt;tt&amp;gt;select&amp;lt;/tt&amp;gt; attribute locates each &amp;lt;tt&amp;gt;title&amp;lt;/tt&amp;gt; element of each given &amp;lt;tt&amp;gt;book&amp;lt;/tt&amp;gt; child of &amp;lt;tt&amp;gt;books&amp;lt;/tt&amp;gt;. The latter simply re-selects (for a different purpose) the node already established by the containing &amp;lt;tt&amp;gt;xsl:for-each&amp;lt;/tt&amp;gt;. (By the way, note in this example the period, also called the &amp;quot;full stop,&amp;quot; which may be familiar to you from its occasional use in directory paths.)&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;
In XSLT, template rules may invoke other template rules, using the &amp;lt;tt&amp;gt;xsl:apply-templates&amp;lt;/tt&amp;gt; element. The &amp;lt;tt&amp;gt;select&amp;lt;/tt&amp;gt; attribute of this element directs the XSLT processor to next process any template rule that matches the indicated relative location path. Thus, the example template rule I just provided could also be coded in the form of two separate template rules, like this:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;xsl:template match=&amp;quot;/books&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;xsl:apply-templates select=&amp;quot;'''book/title'''&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;/xsl:template&amp;gt;&lt;br /&gt;
 &amp;lt;xsl:template match=&amp;quot;'''book/title'''&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;xsl:value-of select=&amp;quot;.&amp;quot;/&amp;gt;&lt;br /&gt;
 &amp;lt;/xsl:template&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The practical effect of a stylesheet structured in this way is that only one template rule's match pattern may be an absolute location path; all others will &amp;quot;trickle down&amp;quot; to successively lower-level template rules, chained together by linking the &amp;lt;tt&amp;gt;select&amp;lt;/tt&amp;gt; attributes of &amp;lt;tt&amp;gt;xsl:apply-templates&amp;lt;/tt&amp;gt; elements to the corresponding template rules (even when the latter's &amp;lt;tt&amp;gt;match&amp;lt;/tt&amp;gt; attributes specify absolute rather than relative paths).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Compound Location Paths ===&lt;br /&gt;
&lt;br /&gt;
It's frequently desirable to select not just the nodes found by way of a single location path, but all the nodes found by way of two or more paths. This is accomplished using the union operator, a &amp;quot;pipe&amp;quot; or vertical-bar character, (&amp;lt;tt&amp;gt;|&amp;lt;/tt&amp;gt;), to delimit the constituent paths. (Whitespace on either side of the pipe is not significant.)&lt;br /&gt;
&lt;br /&gt;
Referring back to the sample document depicted in [[XPath and XPointer/Location Steps and Paths#xpathpointer-CHP-3-FIG-1|Figure 3-1]], you could select all the &amp;lt;tt&amp;gt;invoice&amp;lt;/tt&amp;gt; elements ''and'' all the &amp;lt;tt&amp;gt;cust_info&amp;lt;/tt&amp;gt; elements with a single compound location path:&lt;br /&gt;
&lt;br /&gt;
 /customers/customer/invoice | /customers/customer/cust_info&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;
Here, the selected nodes just happen to be elements at the same level of the node tree. As you will soon see, however, there's no particular requirement that this be the case; you can just as easily select a node-set consisting of elements at different levels of the hierarchy and/or nodes of any types at all, elements or otherwise.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Location Steps ==&lt;br /&gt;
&lt;br /&gt;
Location paths are interesting on a grand, macroscopic level. But (at least to my way of thinking) they're essentially unsophisticated, blunt instruments for extracting content from an XML document. All the real action in XPath is found between the slashes in a full location path — in the ''location steps''.&lt;br /&gt;
&lt;br /&gt;
The location steps you've seen so far in this chapter have been extremely simple. They've walked you down into the given XML source document by way of the tree of element nodes, and element nodes only, and only those element nodes with specific names. Easy enough to understand, perhaps (not to deny the value of understandability!), and also arguably the most common sort of location step, but not particularly eye opening. In fact, these elementary location steps have simply taken advantage of various default values and shortcuts for parts of the full location step syntax: the axis, the node test, and the predicate. This syntax is:&lt;br /&gt;
&lt;br /&gt;
 axis::'''nodetest'''[predicate]&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;
As you will see later in this chapter, it's possible for a location step to include multiple predicates — one after the other or even nested.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Of the three components that a location step may contain, only the node test is required. If you omit the axis, you also omit the double colon (::) that delimits it from the node test. If you omit the predicate, you also omit the square brackets (&amp;lt;tt&amp;gt;[&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;]&amp;lt;/tt&amp;gt;) that enclose it.&lt;br /&gt;
&lt;br /&gt;
Before getting into the details of these three pieces of a location step, let's take a look at their general purposes.&lt;br /&gt;
&lt;br /&gt;
=== The Big Picture ===&lt;br /&gt;
&lt;br /&gt;
A common misconception about microscopes, magnifying glasses, telescopes, and binoculars is that they enlarge the image presented to our eyes from some object or other in the real world. Actually, they narrow the field of vision (assuming you're looking into them the right way); the image presented to our eyes always stays the same size. Armed with this information, take a look at [[XPath and XPointer/Location Steps and Paths#xpathpointer-CHP-3-FIG-2|Figure 3-2]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;xpathpointer-CHP-3-FIG-2&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 3-2. Narrowing the field of vision: &amp;quot;seeing&amp;quot; just boats with sails in a particular direction'''&lt;br /&gt;
&lt;br /&gt;
[[Image:XPath and XPointer_I_3_tt63.png|Narrowing the field of vision: &amp;quot;seeing&amp;quot; just boats with sails in a particular direction]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here, you're standing on the rock at the end of a jetty projecting out into a bay, binoculars held to your eyes. Everything outside the field of vision doesn't &amp;quot;exist&amp;quot; for you as long as you're looking through the lenses: the boats on the water behind you and to either side, the colony of seals on the rocks. You have, in effect, no peripheral vision.&lt;br /&gt;
&lt;br /&gt;
But these are special binoculars. Not only can you use the typical thumbwheel to bring perceived objects into and out of focus, or perhaps to zoom in (that is, narrow the field even further) or out. You can also click a button or push a slider along their top edge, which lets you see (in the chosen direction) only boats, or everything but boats, or boats and buoys only, or just those objects whose names begin with the letter &amp;quot;b.&amp;quot; (The lighthouse is within the field of vision, for example, but it doesn't fit any of those types of &amp;quot;target.&amp;quot;) And you can do even finer tuning: light up just those boats that have sails, or black sails only, or those flying pirate flags, or only flying pirate flags with no cannons visible.&lt;br /&gt;
&lt;br /&gt;
There's your XPath location step: the axis selects the direction you're looking; the node test selects particular generic kinds of objects to see; and the predicate highlights only those objects of the right generic kinds that have other specific characteristics.&lt;br /&gt;
&lt;br /&gt;
Let's start by examining the one required portion of a location step: the node test.&lt;br /&gt;
&lt;br /&gt;
=== The Node Test ===&lt;br /&gt;
&lt;br /&gt;
The node test singles out in a document the sort of nodes in which you're interested. You have two approaches here: identify the names you're interested in or identify the types. [[XPath and XPointer/Location Steps and Paths#xpathpointer-CHP-3-TABLE-1|Table 3-1]] summarizes the available options.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;xpathpointer-CHP-3-TABLE-1&amp;quot;&amp;gt;&lt;br /&gt;
'''Table 3-1. Location step node tests'''&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; &lt;br /&gt;
|-&lt;br /&gt;
! To select... !! Use...&lt;br /&gt;
|-&lt;br /&gt;
| elements with a particular name || the element name in which you're interested (e.g., &amp;lt;tt&amp;gt;/books/book&amp;lt;/tt&amp;gt; selects all elements named &amp;lt;tt&amp;gt;book&amp;lt;/tt&amp;gt; that are children of the root element named &amp;lt;tt&amp;gt;books&amp;lt;/tt&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
| elements with any name || an asterisk (&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;) wildcard character in place of the element name (e.g., &amp;lt;tt&amp;gt;/books/*&amp;lt;/tt&amp;gt; selects ''all'' child elements of the root &amp;lt;tt&amp;gt;books&amp;lt;/tt&amp;gt; element, regardless of those child elements' names)&lt;br /&gt;
|-&lt;br /&gt;
| text nodes || The &amp;lt;tt&amp;gt;text( )&amp;lt;/tt&amp;gt; node test (e.g., &amp;lt;tt&amp;gt;paragraph/text( )&amp;lt;/tt&amp;gt; selects all text nodes that are immediate children of the &amp;lt;tt&amp;gt;paragraph&amp;lt;/tt&amp;gt; elements that are children of the context node)&lt;br /&gt;
|-&lt;br /&gt;
| comment nodes || The &amp;lt;tt&amp;gt;comment( )&amp;lt;/tt&amp;gt; node test (e.g., simply using &amp;lt;tt&amp;gt;comment( )&amp;lt;/tt&amp;gt; locates all comments that are children of the context node)&lt;br /&gt;
|-&lt;br /&gt;
| processing instructions with a particular target || The &amp;lt;tt&amp;gt;processing-instruction(target)&amp;lt;/tt&amp;gt; node test (e.g., &amp;lt;tt&amp;gt;/processing-instruction('xml-stylesheet')&amp;lt;/tt&amp;gt; selects all &amp;lt;tt&amp;gt;xml-stylesheet&amp;lt;/tt&amp;gt; PIs which are children of the root node)&lt;br /&gt;
|-&lt;br /&gt;
| processing instructions regardless of the target || The &amp;lt;tt&amp;gt;processing-instruction( )&amp;lt;/tt&amp;gt; node test (e.g., &amp;lt;tt&amp;gt;/processing-instruction( )&amp;lt;/tt&amp;gt; selects ''all'' PIs that are children of the root node)&lt;br /&gt;
|-&lt;br /&gt;
| all nodes, regardless of their type or name || The &amp;lt;tt&amp;gt;node( )&amp;lt;/tt&amp;gt; node test (e.g., in an XHTML source document, &amp;lt;tt&amp;gt;/html/node( )&amp;lt;/tt&amp;gt; locates not only the &amp;lt;tt&amp;gt;meta&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;head&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;body&amp;lt;/tt&amp;gt; elements, but also any comments and/or PIs that are children of the root &amp;lt;tt&amp;gt;html&amp;lt;/tt&amp;gt; element)&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Neither attributes nor namespace nodes can be located using the node test alone. You must use an axis in a location step to locate these two node types. See the information about the &amp;lt;tt&amp;gt;attribute&amp;lt;/tt&amp;gt;:: and &amp;lt;tt&amp;gt;namespace&amp;lt;/tt&amp;gt;:: axes later in this chapter for more information.&lt;br /&gt;
&lt;br /&gt;
One other point: Note that the &amp;lt;tt&amp;gt;text( )&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;comment( )&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;processing-instruction( )&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;node( )&amp;lt;/tt&amp;gt; node tests — technically called node ''type'' tests — are not functions, and all require the use of parentheses even though the parentheses are empty. This distinguishes these node tests from those simply seeking elements whose ''names'' just happen to be, for example, &amp;lt;tt&amp;gt;comment&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;text&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== The Axis ===&lt;br /&gt;
&lt;br /&gt;
Having determined that you want a location step (via the node test) to &amp;quot;see&amp;quot; only nodes of a certain kind, you can specify the direction — the line of sight, if you will — in which you want to see them. (The direction is always relative to the context node at the point of the location step.) This is accomplished using an axis.&lt;br /&gt;
&lt;br /&gt;
The XPath spec defines 13 different axes, many of which are modeled on a &amp;quot;family&amp;quot; view of the source document's nodes. That is, in a genealogical family tree, each person represents a node; each node (except the one at the very top) has a parent and ancestors, many have children and other descendants, siblings, and so on. So it is in an XML source document, which — thanks to the rules of well-formedness — always contains at least two strictly structured nodes (the root node and the root element).&lt;br /&gt;
&lt;br /&gt;
Let's take a look at a summary of the 13 axes first, presented as [[XPath and XPointer/Location Steps and Paths#xpathpointer-CHP-3-TABLE-2|Table 3-2]]. (I use the word &amp;quot;visible&amp;quot; in this table advisedly. I mean, of course, whether nodes of a given type are visible to an XPath-aware processor — not whether they're visible to a human reader of the document. By the latter standard, whitespace-only text nodes might be considered &amp;quot;invisible,&amp;quot; even though they're just as substantial to a processor as any other nodes in the tree.)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;xpathpointer-CHP-3-TABLE-2&amp;quot;&amp;gt;&lt;br /&gt;
'''Table 3-2. Location step axes'''&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; &lt;br /&gt;
|-&lt;br /&gt;
! Axis !! Description !! Direction !! Visible node types&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
&lt;br /&gt;
 child::&lt;br /&gt;
| Locates node(s) immediately descended from the context node || Forward || Elements, comments, PIs, text nodes&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
&lt;br /&gt;
 parent::&lt;br /&gt;
| Locates the one node immediately above the context node in the node tree || Reverse || Root node, elements&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
&lt;br /&gt;
 descendant::&lt;br /&gt;
| Extends the &amp;lt;tt&amp;gt;child&amp;lt;/tt&amp;gt;:: axis all the way down the node tree, locating children, children of children, and so on || Forward || Elements, comments, PIs, text nodes&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
&lt;br /&gt;
 ancestor::&lt;br /&gt;
| Extends the &amp;lt;tt&amp;gt;parent&amp;lt;/tt&amp;gt;:: axis all the way up the node tree, locating parents, parents of parents, and so on || Reverse || Root node, elements&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
&lt;br /&gt;
 descendant-or-self::&lt;br /&gt;
| Like the &amp;lt;tt&amp;gt;descendant&amp;lt;/tt&amp;gt;:: axis, but locates the context node itself as well as all descendants || Forward || Any but attributes or namespaces&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
&lt;br /&gt;
 ancestor-or-self::&lt;br /&gt;
| Like the &amp;lt;tt&amp;gt;ancestor&amp;lt;/tt&amp;gt;:: axis, but locates the context node itself as well as all ancestors || Reverse || Root node, elements&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
&lt;br /&gt;
 following::&lt;br /&gt;
| Locates all visible nodes that follow the context node (excludes descendants) || Forward || Any but root node, attributes, or namespaces&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
&lt;br /&gt;
 preceding::&lt;br /&gt;
| Locates all visible nodes that precede the context node (excludes ancestors) || Reverse || Any but root node, attributes, or namespaces&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
&lt;br /&gt;
 following-sibling::&lt;br /&gt;
| Locates all visible nodes that both follow the context node and share the same parent || Forward || Any but root node, attributes, or namespaces&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
&lt;br /&gt;
 preceding-sibling::&lt;br /&gt;
| Locates all visible nodes that both precede the context node and share the same parent || Reverse || Any but root node, attributes, or namespaces&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
&lt;br /&gt;
 attribute::&lt;br /&gt;
| Locates attributes of the context node || Forward || Attributes only&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
&lt;br /&gt;
 namespace::&lt;br /&gt;
| Locates namespace nodes || Forward || Namespaces only&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
&lt;br /&gt;
 self::&lt;br /&gt;
| Locates the context node itself || (N/A) || Any&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In this table, note that each axis is designated as a forward or reverse axis. These terms refer to the direction, relative to the context node, in which nodes are visible — in document order or reverse document order, respectively.&lt;br /&gt;
&lt;br /&gt;
Now let's look at some nuances of using axes in your own XPath location steps.&lt;br /&gt;
&lt;br /&gt;
==== Defaults and shortcuts ====&lt;br /&gt;
&lt;br /&gt;
First, there's a default axis, &amp;lt;tt&amp;gt;child&amp;lt;/tt&amp;gt;::. Therefore, the following two location steps are functionally identical:&lt;br /&gt;
&lt;br /&gt;
 child::circle&lt;br /&gt;
 circle&lt;br /&gt;
&lt;br /&gt;
Both locate all &amp;lt;tt&amp;gt;circle&amp;lt;/tt&amp;gt; elements that are children of the context node.&lt;br /&gt;
&lt;br /&gt;
Steps that access the parent node via the &amp;lt;tt&amp;gt;parent&amp;lt;/tt&amp;gt;:: axis in XPath, as in common filesystem directory path syntaxes, can be abbreviated using a double period. These two location steps are thus equivalent:&lt;br /&gt;
&lt;br /&gt;
 parent::node(  )&lt;br /&gt;
 ..&lt;br /&gt;
&lt;br /&gt;
Similarly, the &amp;lt;tt&amp;gt;self&amp;lt;/tt&amp;gt;:: axis can be abbreviated with a single period. (As with the &amp;lt;tt&amp;gt;parent&amp;lt;/tt&amp;gt;:: axis, this is technically an abbreviation for the axis in combination with the &amp;lt;tt&amp;gt;node( )&amp;lt;/tt&amp;gt; node test.)&lt;br /&gt;
&lt;br /&gt;
When using the &amp;lt;tt&amp;gt;parent::&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;self::&amp;lt;/tt&amp;gt; axes, you almost never have to specify the name of the node in question; no node in an XML document ever has more than one parent or &amp;quot;self,&amp;quot; and the name of that parent/self node is thus almost always immaterial. The exception is when a given element type may appear at any of several levels of a document conforming to a given vocabulary, and you want to select only those with a particular parent element type.&lt;br /&gt;
&lt;br /&gt;
Note that the &amp;lt;tt&amp;gt;self&amp;lt;/tt&amp;gt;:: axis is useful for testing the name of the context node in the predicate portion of a location step. (Predicates are covered in the next section of this chapter.) The &amp;lt;tt&amp;gt;name( )&amp;lt;/tt&amp;gt; XPath function, covered in [[XPath and XPointer/XPath Functions and Numeric Operators|Chapter 4]], can also be used for this purpose. However, the &amp;lt;tt&amp;gt;self&amp;lt;/tt&amp;gt;:: axis is &amp;quot;namespace aware&amp;quot; and works specifically with the namespace prefix supplied as the tested value; the &amp;lt;tt&amp;gt;name( )&amp;lt;/tt&amp;gt; function permits the processor to substitute any prefix it wants, as long as the namespace URI is correctly mapped. Consider these two examples:&lt;br /&gt;
&lt;br /&gt;
 self::someprefix:somename&lt;br /&gt;
 name(  )=&amp;quot;someprefix:somename&amp;quot;&lt;br /&gt;
&lt;br /&gt;
The first example is true only if the context node's name is &amp;quot;somename&amp;quot; ''and'' its namespace prefix is &amp;quot;someprefix&amp;quot;; the second is true if the context node's name is &amp;quot;somename&amp;quot; ''and'' its namespace prefix, whatever it is, maps to the same namespace URI as does &amp;quot;someprefix.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
When seeking content along the &amp;lt;tt&amp;gt;attribute&amp;lt;/tt&amp;gt;:: axis, you can replace that axis with a simple at sign (&amp;lt;tt&amp;gt;@&amp;lt;/tt&amp;gt;). Both of the following location steps locate the &amp;lt;tt&amp;gt;copyright&amp;lt;/tt&amp;gt; attribute of the context node:&lt;br /&gt;
&lt;br /&gt;
 attribute::copyright&lt;br /&gt;
 @copyright&lt;br /&gt;
&lt;br /&gt;
Finally, while not strictly a shortcut for an axis, the location step (plus separators) &amp;lt;tt&amp;gt;/descendant-or-self::node( )/&amp;lt;/tt&amp;gt; can be abbreviated with a simple double slash, &amp;lt;tt&amp;gt;//&amp;lt;/tt&amp;gt;. Here's a sample document, a peek into a particularly unruly kitchen pantry (entirely fictional, of course):&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;pantry&amp;gt;&lt;br /&gt;
    &amp;lt;shelf&amp;gt;&lt;br /&gt;
       &amp;lt;supplies&amp;gt;&lt;br /&gt;
          &amp;lt;paper_goods&amp;gt;&lt;br /&gt;
             &amp;lt;paper_good&amp;gt;paper towels&amp;lt;/paper_good&amp;gt;&lt;br /&gt;
             &amp;lt;paper_good&amp;gt;paper plates&amp;lt;/paper_good&amp;gt;&lt;br /&gt;
          &amp;lt;/paper_goods&amp;gt;&lt;br /&gt;
       &amp;lt;/supplies&amp;gt;&lt;br /&gt;
       &amp;lt;snack_foods&amp;gt;&lt;br /&gt;
          &amp;lt;snack_food&amp;gt;popcorn&amp;lt;/snack_food&amp;gt;&lt;br /&gt;
          &amp;lt;snack_food&amp;gt;chips&amp;lt;/snack_food&amp;gt;&lt;br /&gt;
       &amp;lt;/snack_foods&amp;gt;&lt;br /&gt;
    &amp;lt;/shelf&amp;gt;&lt;br /&gt;
    &amp;lt;shelf&amp;gt;&lt;br /&gt;
       &amp;lt;supplies&amp;gt;&lt;br /&gt;
          &amp;lt;paper_goods&amp;gt;&lt;br /&gt;
             &amp;lt;paper_good&amp;gt;napkins&amp;lt;/paper_good&amp;gt;&lt;br /&gt;
          &amp;lt;/paper_goods&amp;gt;&lt;br /&gt;
       &amp;lt;/supplies&amp;gt;&lt;br /&gt;
       &amp;lt;snack_foods&amp;gt;&lt;br /&gt;
          &amp;lt;snack_food&amp;gt;dried tofu&amp;lt;/snack_food&amp;gt;&lt;br /&gt;
       &amp;lt;/snack_foods&amp;gt;&lt;br /&gt;
    &amp;lt;/shelf&amp;gt;&lt;br /&gt;
 &amp;lt;/pantry&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To locate all &amp;lt;tt&amp;gt;snack_food&amp;lt;/tt&amp;gt; elements descended from this document's root &amp;lt;tt&amp;gt;pantry&amp;lt;/tt&amp;gt; element, no matter where they are in its tree of descendants, either of the following will suffice:&lt;br /&gt;
&lt;br /&gt;
 /pantry/descendant-or-self::node(  )/snack_food&lt;br /&gt;
 /pantry//snack_food&lt;br /&gt;
&lt;br /&gt;
If locating all nodes of a particular name or type, the double slash can begin the location path alone — there is no need to precede them with yet another slash representing the root node. For instance, to locate all elements in a document, use:&lt;br /&gt;
&lt;br /&gt;
 //*&lt;br /&gt;
&lt;br /&gt;
and ''not'':&lt;br /&gt;
&lt;br /&gt;
 ///*&lt;br /&gt;
&lt;br /&gt;
The double-slash shortcut is so useful that you will probably find yourself using it as a shortcut for the &amp;lt;tt&amp;gt;descendant::node( )&amp;lt;/tt&amp;gt; location step as well — failing to recognize a potential pitfall in doing so: the double slash is ''not'' associated with just the &amp;lt;tt&amp;gt;descendant::node( )&amp;lt;/tt&amp;gt; location step, but with the &amp;lt;tt&amp;gt;descendant&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;'''-or-self'''&amp;lt;/tt&amp;gt;::&amp;lt;tt&amp;gt;node( )&amp;lt;/tt&amp;gt; location step. In many cases, the results of using either are identical. For instance:&lt;br /&gt;
&lt;br /&gt;
 /pantry//snack_food&lt;br /&gt;
&lt;br /&gt;
works because selecting &amp;quot;all descendants of the &amp;lt;tt&amp;gt;pantry&amp;lt;/tt&amp;gt; element, as well as the &amp;lt;tt&amp;gt;pantry&amp;lt;/tt&amp;gt; element itself, as long as the given node is a &amp;lt;tt&amp;gt;snack_food&amp;lt;/tt&amp;gt; element&amp;quot; obviously eliminates the &amp;lt;tt&amp;gt;pantry&amp;lt;/tt&amp;gt; element itself, leaving only the &amp;lt;tt&amp;gt;snack_food&amp;lt;/tt&amp;gt; descendants.&lt;br /&gt;
&lt;br /&gt;
But if you use the wildcard asterisk or the &amp;lt;tt&amp;gt;node( )&amp;lt;/tt&amp;gt; node test together with the double slash, you may get a surprise. The following two location paths each select the &amp;lt;tt&amp;gt;pantry&amp;lt;/tt&amp;gt; element in addition to all the desired descendants:&lt;br /&gt;
&lt;br /&gt;
 /pantry//*&lt;br /&gt;
 /pantry//node(  )&lt;br /&gt;
&lt;br /&gt;
==== Restrictions by context node type ====&lt;br /&gt;
&lt;br /&gt;
The last column in [[XPath and XPointer/Location Steps and Paths#xpathpointer-CHP-3-TABLE-2|Table 3-2]] shows which node types are visible, looking from the context node along the indicated axis. However, it's also important to note that the axes available at a given moment vary depending on the type of the context node. An XPath processor will not reject outright invalid axis/context node type combinations; it will simply return an empty node-set for that location step. [[XPath and XPointer/Location Steps and Paths#xpathpointer-CHP-3-TABLE-3|Table 3-3]] summarizes these restrictions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;xpathpointer-CHP-3-TABLE-3&amp;quot;&amp;gt;&lt;br /&gt;
'''Table 3-3. Valid axis/context node combinations'''&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; &lt;br /&gt;
|-&lt;br /&gt;
! Axis !! Use when context node type is&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
&lt;br /&gt;
 child::&lt;br /&gt;
| Root or element&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
&lt;br /&gt;
 parent::&lt;br /&gt;
| Any but the root node (which has no parent)&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
&lt;br /&gt;
 descendant::&lt;br /&gt;
| Root or element&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
&lt;br /&gt;
 ancestor::&lt;br /&gt;
| Any but the root node (which has no ancestors)&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
&lt;br /&gt;
 descendant-or-self::&lt;br /&gt;
| Root or element&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
&lt;br /&gt;
 ancestor-or-self::&lt;br /&gt;
| Any&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
&lt;br /&gt;
 following::&lt;br /&gt;
| Any but root, attribute, or namespace&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
&lt;br /&gt;
 preceding::&lt;br /&gt;
| Any but root, attribute, or namespace&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
&lt;br /&gt;
 following-sibling::&lt;br /&gt;
| Any but root, attribute, or namespace&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
&lt;br /&gt;
 preceding-sibling::&lt;br /&gt;
| Any but root, attribute, or namespace&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
&lt;br /&gt;
 attribute::&lt;br /&gt;
| Element&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
&lt;br /&gt;
 namespace::&lt;br /&gt;
| Element&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
&lt;br /&gt;
 self::&lt;br /&gt;
| Any&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&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;
A curious side effect of the information in [[XPath and XPointer/Location Steps and Paths#xpathpointer-CHP-3-TABLE-2|Table 3-2]] and [[XPath and XPointer/Location Steps and Paths#xpathpointer-CHP-3-TABLE-3|Table 3-3]], taken together, is that although attribute and namespace nodes &amp;quot;belong to&amp;quot; their declaring elements — in the sense that such an element acts as an attribute/namespace node's parent and is therefore visible along the &amp;lt;tt&amp;gt;parent&amp;lt;/tt&amp;gt;:: axis — the reverse is not true: you can't see attribute or namespace nodes along an element's &amp;lt;tt&amp;gt;child&amp;lt;/tt&amp;gt;:: axis.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Axes and efficiency ====&lt;br /&gt;
&lt;br /&gt;
Something to remember when selecting axes to navigate around your XML documents is while the end result achieved by using one axis may be identical to that achieved by using another, one ''means'' to the end may be significantly more efficient than another. The following XML document illustrates this:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;dictionary&amp;gt;&lt;br /&gt;
    &amp;lt;letter&amp;gt;&lt;br /&gt;
       &amp;lt;forms&amp;gt;&lt;br /&gt;
          &amp;lt;form type=&amp;quot;upper&amp;quot;&amp;gt;A&amp;lt;/form&amp;gt;&lt;br /&gt;
          &amp;lt;form type=&amp;quot;lower&amp;quot;&amp;gt;a&amp;lt;/form&amp;gt;&lt;br /&gt;
       &amp;lt;/forms&amp;gt;&lt;br /&gt;
       &amp;lt;word&amp;gt;&lt;br /&gt;
          &amp;lt;spelling&amp;gt;aardvark&amp;lt;/spelling&amp;gt;&lt;br /&gt;
          &amp;lt;part_of_speech&amp;gt;noun&amp;lt;/part_of_speech&amp;gt;&lt;br /&gt;
          &amp;lt;definition&amp;gt;a nocturnal mammal of southern Africa with a tubular&lt;br /&gt;
          snout and a long tongue&amp;lt;/definition&amp;gt;&lt;br /&gt;
       &amp;lt;/word&amp;gt;&lt;br /&gt;
    &amp;lt;/letter&amp;gt;&lt;br /&gt;
 &amp;lt;/dictionary&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Both of the following location paths locate the &amp;lt;tt&amp;gt;definition&amp;lt;/tt&amp;gt; element:&lt;br /&gt;
&lt;br /&gt;
 //definition&lt;br /&gt;
 /dictionary/letter/word/definition&lt;br /&gt;
&lt;br /&gt;
The second, however, is a much more direct route to the desired result. It leads the processor down the tree with no side trips, right to the &amp;lt;tt&amp;gt;definition&amp;lt;/tt&amp;gt; element. The first, in contrast, takes a leisurely stroll through all descendants of the root node, picking up each one in turn and mulling it over (&amp;quot;Hmm, is this descendant a &amp;lt;tt&amp;gt;dictionary&amp;lt;/tt&amp;gt; element . . . ?&amp;quot;) before proceeding further through the tree. This includes irrelevant detours into the &amp;lt;tt&amp;gt;forms&amp;lt;/tt&amp;gt; branch of the tree and to the &amp;lt;tt&amp;gt;spelling&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;part_of_speech&amp;lt;/tt&amp;gt; siblings of the &amp;lt;tt&amp;gt;dictionary&amp;lt;/tt&amp;gt; node.&lt;br /&gt;
&lt;br /&gt;
Of course, for this extremely simple example document, the difference in processing time is negligible. Turn this document into an entire dictionary, though, and the difference is considerable. (Of course, explicitly coding the full path to a desired descendant can be more tedious — especially for large, deep node trees. It's hard to argue with performance results, though.)&lt;br /&gt;
&lt;br /&gt;
=== The Predicate ===&lt;br /&gt;
&lt;br /&gt;
Those of you who may have suffered under the yoke of English grammar lessons may be familiar with the term &amp;quot;predicate&amp;quot; as it's commonly used there: the predicate of the sentence is the verb — the word or phrase that drives the sentence's action. So it is with the optional predicate portion of a location step, which drives the filtering performed by the rest of the step to its finest level of granularity.&lt;br /&gt;
&lt;br /&gt;
A more useful way to understand the term as it's used in XPath, though, is to think of its form in such constructions as &amp;quot;Whether Result X will be true is ''predicated'' upon the truth of Condition Y.&amp;quot; That's because a location step's predicate sets forth a Boolean test: if the Boolean test returns true (for a given node selected by the preceding portion of the step), then this node will be selected for inclusion in the resulting node-set. In all other cases, the node is disregarded.&lt;br /&gt;
&lt;br /&gt;
As with Boolean tests in other languages, XPath's predicates are usually coded (within the enclosing square brackets) as Boolean statements of the general form:&lt;br /&gt;
&lt;br /&gt;
                ''value1'' &lt;br /&gt;
                ''operator value2''&lt;br /&gt;
             &lt;br /&gt;
&lt;br /&gt;
where:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tt&amp;gt;''value1''&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;''value2''&amp;lt;/tt&amp;gt; are XPath expressions.&lt;br /&gt;
* The whitespace to either side of &amp;lt;tt&amp;gt;''operator''&amp;lt;/tt&amp;gt; is not significant — there can be whitespace there for legibility, or not; and&lt;br /&gt;
* &amp;lt;tt&amp;gt;''operator''&amp;lt;/tt&amp;gt; is one of the Boolean operators listed in [[XPath and XPointer/Location Steps and Paths#xpathpointer-CHP-3-TABLE-4|Table 3-4]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;xpathpointer-CHP-3-TABLE-4&amp;quot;&amp;gt;&lt;br /&gt;
'''Table 3-4. Boolean operators in XPath predicates'''&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; &lt;br /&gt;
|-&lt;br /&gt;
! Operator !! Meaning&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
&lt;br /&gt;
 =&lt;br /&gt;
| Equal to&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
&lt;br /&gt;
 !=&lt;br /&gt;
| Not equal to&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&lt;br /&gt;
| Greater than&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
&lt;br /&gt;
 &amp;gt;=&lt;br /&gt;
| Greater than or equal to&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;&lt;br /&gt;
| Less than&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;=&lt;br /&gt;
| Less than or equal to&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&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;
If (as is likely) you're using XPath expressions within XML documents (as opposed to scripting languages), you must escape any operators that might cause your documents to fail well-formedness constraints. For instance, the &amp;lt;tt&amp;gt;&amp;lt;&amp;lt;/tt&amp;gt; character will need to be escaped as &amp;lt;tt&amp;gt;&amp;amp;amp;lt;&amp;lt;/tt&amp;gt;, and the &amp;lt;tt&amp;gt;&amp;gt;&amp;lt;/tt&amp;gt; may need to be escaped using &amp;lt;tt&amp;gt;&amp;amp;amp;gt;&amp;lt;/tt&amp;gt;. (When used in an attribute value, the greater-than operator (&amp;lt;tt&amp;gt;&amp;gt;)&amp;lt;/tt&amp;gt; never needs to be escaped.)&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As I mentioned, the two values being compared by the operator can be either location paths in their own right or literal values. Importantly, any relative location paths appearing in the predicate are considered relative to the context node established by the portions of the location step that precede the predicate, ''not'' relative to the context node in effect for the location step as a whole. Consider the following simple XML document:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;person name=&amp;quot;John&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;child name=&amp;quot;John&amp;quot;/&amp;gt;&lt;br /&gt;
    &amp;lt;child name=&amp;quot;Connie&amp;quot;/&amp;gt;&lt;br /&gt;
    &amp;lt;child name=&amp;quot;Cindy&amp;quot;/&amp;gt;&lt;br /&gt;
    &amp;lt;child name=&amp;quot;Mike&amp;quot;/&amp;gt;&lt;br /&gt;
 &amp;lt;/person&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Given this document, consider this location path, paying special attention to the predicate:&lt;br /&gt;
&lt;br /&gt;
 /person/'''child[@name='John']'''&lt;br /&gt;
             &lt;br /&gt;
&lt;br /&gt;
The context node for the final location step as a whole is the &amp;lt;tt&amp;gt;person&amp;lt;/tt&amp;gt; element. The predicate does ''not'' look at the &amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt; attribute of the &amp;lt;tt&amp;gt;person&amp;lt;/tt&amp;gt; element, however, but rather at the &amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt; attribute of each &amp;lt;tt&amp;gt;child&amp;lt;/tt&amp;gt; element. Thus, this predicate results in the selection of only the first &amp;lt;tt&amp;gt;child&amp;lt;/tt&amp;gt; element.&lt;br /&gt;
&lt;br /&gt;
Note that the Boolean condition established by the predicate is an &amp;quot;''any'' node that...&amp;quot; rather than an &amp;quot;''all'' nodes that...&amp;quot; condition. For instance, given the above document, the following location path selects the root &amp;lt;tt&amp;gt;person&amp;lt;/tt&amp;gt; element as long as ''any'' of its &amp;lt;tt&amp;gt;child&amp;lt;/tt&amp;gt; children has the indicated &amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt; attribute value; the selection doesn't require that ''all'' its &amp;lt;tt&amp;gt;child&amp;lt;/tt&amp;gt; children meet the test.&lt;br /&gt;
&lt;br /&gt;
 /person[child/@name='Cindy']&lt;br /&gt;
&lt;br /&gt;
There's no restriction on the number of location steps that might employ predicates, although the simple examples above show predicates only on the last step. In navigating around an XHTML document with XPath, you might use a location path such as this:&lt;br /&gt;
&lt;br /&gt;
 /html/body/p'''[@align=&amp;quot;center&amp;quot;]'''/img'''[@border &amp;amp;amp;gt; 0]'''&lt;br /&gt;
             &lt;br /&gt;
&lt;br /&gt;
This selects each &amp;lt;tt&amp;gt;img&amp;lt;/tt&amp;gt; element with a &amp;lt;tt&amp;gt;border&amp;lt;/tt&amp;gt; attribute greater than 0, as long as the &amp;lt;tt&amp;gt;img&amp;lt;/tt&amp;gt; element's parent is a center-aligned &amp;lt;tt&amp;gt;p&amp;lt;/tt&amp;gt; element that is a child of the &amp;lt;tt&amp;gt;body&amp;lt;/tt&amp;gt; element (which in turn is a child of the &amp;lt;tt&amp;gt;html&amp;lt;/tt&amp;gt; element).&lt;br /&gt;
&lt;br /&gt;
==== Nesting predicates ====&lt;br /&gt;
&lt;br /&gt;
You may not use or encounter this too much in your own XPath location steps, but it's entirely legal for an expression being tested by the predicate to include a predicate of its own. (After all, the expressions on either side of the operator, being expressions, can be and often are location steps in their own right.) Thus, you might see something like this:&lt;br /&gt;
&lt;br /&gt;
 //roofing_material[descendant::type'''[preceding-sibling::manufacturer='Smith']''']&lt;br /&gt;
&lt;br /&gt;
This selects all &amp;lt;tt&amp;gt;roofing_material&amp;lt;/tt&amp;gt; elements that have a &amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt; descendant for which, in turn, there exists a &amp;lt;tt&amp;gt;manufacturer&amp;lt;/tt&amp;gt; on the &amp;lt;tt&amp;gt;preceding-sibling&amp;lt;/tt&amp;gt;:: axis whose name is &amp;quot;Smith.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==== Compound predicates ====&lt;br /&gt;
&lt;br /&gt;
You can test for multiple conditions in a single predicate by delimiting the multiple conditions with logical &amp;lt;tt&amp;gt;and&amp;lt;/tt&amp;gt;/&amp;lt;tt&amp;gt;or&amp;lt;/tt&amp;gt; operators. For instance:&lt;br /&gt;
&lt;br /&gt;
 camera[brand/@name = 'Minolta' '''and''' brand/@list &amp;amp;amp;lt; 300]&lt;br /&gt;
&lt;br /&gt;
selects a &amp;lt;tt&amp;gt;camera&amp;lt;/tt&amp;gt; child of the context node only if:&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;tt&amp;gt;camera&amp;lt;/tt&amp;gt; element has a &amp;lt;tt&amp;gt;brand&amp;lt;/tt&amp;gt; child with a &amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt; attribute whose value is &amp;lt;tt&amp;gt;Minolta&amp;lt;/tt&amp;gt;.&lt;br /&gt;
* The &amp;lt;tt&amp;gt;camera&amp;lt;/tt&amp;gt; element has a &amp;lt;tt&amp;gt;brand&amp;lt;/tt&amp;gt; child, which also has a &amp;lt;tt&amp;gt;list&amp;lt;/tt&amp;gt; attribute whose value is less than 300.&lt;br /&gt;
&lt;br /&gt;
As in other computer languages, using multiple &amp;lt;tt&amp;gt;and&amp;lt;/tt&amp;gt;s and &amp;lt;tt&amp;gt;or&amp;lt;/tt&amp;gt;s can become quickly indecipherable to the human eye and mind, so XPath allows you to group conditions together, using parentheses to eliminate ambiguity. You can nest these grouped conditions to any arbitrary depth.&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;
Note, in the various example predicates here (and anywhere else in the book), the escaping of markup-significant characters (such as &amp;lt;tt&amp;gt;&amp;amp;amp;lt;&amp;lt;/tt&amp;gt; for the &amp;lt;tt&amp;gt;&amp;lt;&amp;lt;/tt&amp;gt; character). The escaping is required ''not'' by XPath itself, but by the constraints imposed on XML documents by the XML spec itself; such documents — for example, XSLT stylesheets — are common (perhaps the most common) venues to find XPath expressions. (That's why I'm escaping them.) But when using XPath outside of an XML or other markup context, there's no particular need to escape the special characters. For example, in a non-markup application, the preceding location step could be coded:&lt;br /&gt;
&lt;br /&gt;
 camera[brand/@name = 'Minolta' and brand/@list '''&amp;lt;''' 300]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Consider this document:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;weather&amp;gt;&lt;br /&gt;
    &amp;lt;day date=&amp;quot;2001-12-12&amp;quot;&amp;gt;&lt;br /&gt;
       &amp;lt;readings&amp;gt;&lt;br /&gt;
          &amp;lt;reading time=&amp;quot;0600&amp;quot;&amp;gt;&lt;br /&gt;
             &amp;lt;temp&amp;gt;23&amp;lt;/temp&amp;gt;&lt;br /&gt;
             &amp;lt;wind_spd&amp;gt;5&amp;lt;/wind_spd&amp;gt;&lt;br /&gt;
             &amp;lt;wind_dir&amp;gt;ESE&amp;lt;/wind_dir&amp;gt;&lt;br /&gt;
          &amp;lt;/reading&amp;gt;&lt;br /&gt;
          &amp;lt;reading time=&amp;quot;1200&amp;quot;&amp;gt;&lt;br /&gt;
             &amp;lt;temp&amp;gt;30&amp;lt;/temp&amp;gt;&lt;br /&gt;
             &amp;lt;wind_spd&amp;gt;2&amp;lt;/wind_spd&amp;gt;&lt;br /&gt;
             &amp;lt;wind_dir&amp;gt;SE&amp;lt;/wind_dir&amp;gt;&lt;br /&gt;
          &amp;lt;/reading&amp;gt;&lt;br /&gt;
          &amp;lt;reading time=&amp;quot;1800&amp;quot;&amp;gt;&lt;br /&gt;
             &amp;lt;temp&amp;gt;34&amp;lt;/temp&amp;gt;&lt;br /&gt;
             &amp;lt;wind_spd&amp;gt;10&amp;lt;/wind_spd&amp;gt;&lt;br /&gt;
             &amp;lt;wind_dir&amp;gt;S&amp;lt;/wind_dir&amp;gt;&lt;br /&gt;
          &amp;lt;/reading&amp;gt;&lt;br /&gt;
          &amp;lt;reading time=&amp;quot;2400&amp;quot;&amp;gt;&lt;br /&gt;
             &amp;lt;temp&amp;gt;29&amp;lt;/temp&amp;gt;&lt;br /&gt;
             &amp;lt;wind_spd&amp;gt;15&amp;lt;/wind_spd&amp;gt;&lt;br /&gt;
             &amp;lt;wind_dir&amp;gt;S&amp;lt;/wind_dir&amp;gt;&lt;br /&gt;
          &amp;lt;/reading&amp;gt;&lt;br /&gt;
       &amp;lt;/readings&amp;gt;&lt;br /&gt;
    &amp;lt;/day&amp;gt;&lt;br /&gt;
 ''   ...etc....''&lt;br /&gt;
 &amp;lt;/weather&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As a hypothetical case, you might be interested only in those readings meeting the following conditions:&lt;br /&gt;
&lt;br /&gt;
* The time at which the reading was taken was either noon or 6 p.m.&lt;br /&gt;
* The wind speed was less than 15 knots, as long as the wind direction was from the south.&lt;br /&gt;
* The temperature was less than 25 degrees.&lt;br /&gt;
&lt;br /&gt;
As a location path, these conditions could be expressed as follows:&lt;br /&gt;
&lt;br /&gt;
 //reading[(@time=&amp;quot;1200&amp;quot; '''or''' @time=&amp;quot;1800&amp;quot;) '''or''' (wind_spd &amp;amp;amp;lt; 15 '''and''' wind_dir=&amp;quot;S&amp;quot;)&lt;br /&gt;
    '''or''' (temp &amp;amp;amp;lt; 25)]&lt;br /&gt;
&lt;br /&gt;
If the connecting operators were all either &amp;lt;tt&amp;gt;and&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;or&amp;lt;/tt&amp;gt;, you wouldn't need to use any grouping at all. The presence of that lone &amp;lt;tt&amp;gt;and&amp;lt;/tt&amp;gt;, though, changes the situation considerably: omit the parentheses, or group (say) the test for &amp;lt;tt&amp;gt;wind_dir&amp;lt;/tt&amp;gt; with the one for &amp;lt;tt&amp;gt;temp&amp;lt;/tt&amp;gt;, and you've suddenly got a subtly (or radically) different test, returning a subtly (or radically) different node-set.&lt;br /&gt;
&lt;br /&gt;
Operator precedence in XPath, in order of ''ascending'' importance, is as follows: &amp;lt;tt&amp;gt;or&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;and&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;!=&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;&amp;lt;=&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;&amp;lt;&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;&amp;gt;=&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;&amp;gt;&amp;lt;/tt&amp;gt;, so in:&lt;br /&gt;
&lt;br /&gt;
 a = b '''or''' c = d '''and''' x = y&lt;br /&gt;
&lt;br /&gt;
the &amp;lt;tt&amp;gt;and&amp;lt;/tt&amp;gt; test takes precedence over the &amp;lt;tt&amp;gt;or&amp;lt;/tt&amp;gt;, being evaluated as though they were coded:&lt;br /&gt;
&lt;br /&gt;
 x = y''' and''' (a = b '''or''' c = d)&lt;br /&gt;
&lt;br /&gt;
When parentheses are used for grouping, conditions are evaluated at their innermost levels first, &amp;quot;boiling up&amp;quot; the respective true or false values to a common level where they can ''then'' be compared using operator precedence and left-to-right rules.&lt;br /&gt;
&lt;br /&gt;
==== Predicates with a single value and no operator ====&lt;br /&gt;
&lt;br /&gt;
Often, you don't need to determine that a node along some axis has some particular value. You need merely to check for the ''existence'' of such a node. The way to use an XPath predicate for this purpose is to take advantage of a special form of the predicate, which simply uses a location path with no &amp;lt;tt&amp;gt;''operator''&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;''value2''&amp;lt;/tt&amp;gt; within the square brackets.&lt;br /&gt;
&lt;br /&gt;
You could select only &amp;lt;tt&amp;gt;book&amp;lt;/tt&amp;gt; elements that contain at least one &amp;lt;tt&amp;gt;table&amp;lt;/tt&amp;gt;, for example:&lt;br /&gt;
&lt;br /&gt;
 //book['''descendant::table''']&lt;br /&gt;
&lt;br /&gt;
This works because XPath treats an empty node-set as a Boolean false and a ''non''-empty node-set as a Boolean true.&lt;br /&gt;
&lt;br /&gt;
Note that this does not disregard a &amp;lt;tt&amp;gt;book&amp;lt;/tt&amp;gt; element that contains an empty &amp;lt;tt&amp;gt;table&amp;lt;/tt&amp;gt; element; it tests for the presence of ''any'' &amp;lt;tt&amp;gt;table&amp;lt;/tt&amp;gt; element, empty or otherwise. If you want to be sure you're selecting only those &amp;lt;tt&amp;gt;book&amp;lt;/tt&amp;gt; elements with non-empty &amp;lt;tt&amp;gt;table&amp;lt;/tt&amp;gt; descendants, you use an explicit test in the predicate:&lt;br /&gt;
&lt;br /&gt;
 //book[descendant::table!=&amp;quot;&amp;quot;]&lt;br /&gt;
&lt;br /&gt;
An earlier note back discussed the general silliness of selecting a node with a particular name on the &amp;lt;tt&amp;gt;parent&amp;lt;/tt&amp;gt;:: axis, because that axis will always locate at most a single node (irrespective of its name). (The root node has no parent, but all other nodes in a document have exactly one parent.) In some XML vocabularies, though, a particular element type may be allowed as a child of ''different'' element types. A classic case is the XHTML &amp;lt;tt&amp;gt;div&amp;lt;/tt&amp;gt; element, which can appear as a container almost anywhere within the body of an XHTML document. Thus, you can productively use the &amp;lt;tt&amp;gt;parent&amp;lt;/tt&amp;gt;:: axis in a case like this, within a single-valued predicate, to isolate (say) only those &amp;lt;tt&amp;gt;div&amp;lt;/tt&amp;gt; elements that are children of a &amp;lt;tt&amp;gt;p&amp;lt;/tt&amp;gt; element:&lt;br /&gt;
&lt;br /&gt;
 //div[parent::p]&lt;br /&gt;
&lt;br /&gt;
On the other hand, there are often a number of other approaches to the same problem, including the (to my mind) much simpler and easier to digest:&lt;br /&gt;
&lt;br /&gt;
 //p/div&lt;br /&gt;
&lt;br /&gt;
The point here is not to argue the merits of one approach or another in general; it's simply to remind you that as a rule, XPath offers multiple routes to the same solution. If you find yourself trapped by a particular technique that &amp;quot;solves&amp;quot; one problem but creates another, don't forget to investigate an alternative before consigning XPath to the (ever more crowded) dustbin of technologies long on the theoretical dimension but short on the practical.&lt;br /&gt;
&lt;br /&gt;
==== Special case: numeric-valued predicates ====&lt;br /&gt;
&lt;br /&gt;
A very important second exception to the general form of the predicate is when the predicate's value is (or evaluates to) a number. This form is used to select a node that has a particular context position within the node-set selected by the preceding portion of the location step.&lt;br /&gt;
&lt;br /&gt;
Look back at the weather-readings example. If you wanted to select the third &amp;lt;tt&amp;gt;reading&amp;lt;/tt&amp;gt; child of all elements in the document, regardless of its contents, you could do so using:&lt;br /&gt;
&lt;br /&gt;
 //reading['''3''']&lt;br /&gt;
&lt;br /&gt;
This numeric form of the predicate is actually an abbreviated form of the usual &amp;lt;tt&amp;gt;''value1''&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;''operator''&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;''value2''&amp;lt;/tt&amp;gt; general syntax. The full form uses the XPath &amp;lt;tt&amp;gt;position( )&amp;lt;/tt&amp;gt; function (covered in [[XPath and XPointer/XPath Functions and Numeric Operators|Chapter 4]]) in the following fashion:&lt;br /&gt;
&lt;br /&gt;
 //reading[position(  ) = 3]&lt;br /&gt;
&lt;br /&gt;
Note that to test a node's position and some other condition in a compound predicate, you may ''not'' use the short, numeric form of the position test. Thus, the following:&lt;br /&gt;
&lt;br /&gt;
 //reading['''3''' or temp &amp;amp;amp;lt; 25]&lt;br /&gt;
&lt;br /&gt;
is ''not'' correct, and must be coded as:&lt;br /&gt;
&lt;br /&gt;
 //reading['''position(  ) = 3''' or temp &amp;amp;amp;lt; 25]&lt;br /&gt;
&lt;br /&gt;
==== &amp;quot;Stacked&amp;quot; predicates ====&lt;br /&gt;
&lt;br /&gt;
The XPath spec doesn't use this term, but I think the word &amp;quot;stacked&amp;quot; pretty well describes what's going on. (&amp;quot;Chained&amp;quot; might work equally well. But in a chain, the order of the particular objects usually doesn't make much difference; switch a couple of links and it's still functionally the same chain. In a stack, the sequence can make all the difference in the world.) A location step can have multiple predicates, one following the other, in this fashion:&lt;br /&gt;
&lt;br /&gt;
 axis::nodetest[predicate1]...[predicateN]&lt;br /&gt;
&lt;br /&gt;
where the ellipsis (&amp;lt;tt&amp;gt;...&amp;lt;/tt&amp;gt;) and [&amp;lt;tt&amp;gt;predicateN&amp;lt;/tt&amp;gt;] indicate that you can have as many predicates as you need.&lt;br /&gt;
&lt;br /&gt;
In many cases, this works exactly as though you'd put the stacked predicates together in a single predicate and connected them with &amp;lt;tt&amp;gt;and&amp;lt;/tt&amp;gt; operators. For instance, the following two location steps are functionally identical:&lt;br /&gt;
&lt;br /&gt;
 day[@date &amp;amp;amp;gt; &amp;quot;2001-12-01&amp;quot;][reading]&lt;br /&gt;
 day[@date &amp;amp;amp;gt; &amp;quot;2001-12-01&amp;quot; and reading]&lt;br /&gt;
&lt;br /&gt;
Both select a &amp;lt;tt&amp;gt;day&amp;lt;/tt&amp;gt; element only if it has a &amp;lt;tt&amp;gt;date&amp;lt;/tt&amp;gt; attribute whose value is greater than &amp;lt;tt&amp;gt;2001-12-01&amp;lt;/tt&amp;gt; ''and'' if it has at least one &amp;lt;tt&amp;gt;reading&amp;lt;/tt&amp;gt; child.&lt;br /&gt;
&lt;br /&gt;
But the operation of these stacked predicates is slightly different from the merely &amp;lt;tt&amp;gt;and&amp;lt;/tt&amp;gt;ed-together alternative. In effect, each succeeding stacked predicate is evaluated in terms of the narrowed context provided by the preceding one(s), ''not'' just in terms of the general context in which a single (perhaps compound) predicate is evaluated. This is especially noticeable when one of the predicates on the stack is numeric, testing for a node's position.&lt;br /&gt;
&lt;br /&gt;
Consider a document that represents tosses of a coin:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tosses&amp;gt;&lt;br /&gt;
    &amp;lt;toss result=&amp;quot;heads&amp;quot;/&amp;gt;&lt;br /&gt;
    &amp;lt;toss result=&amp;quot;heads&amp;quot;/&amp;gt;&lt;br /&gt;
    &amp;lt;toss result=&amp;quot;tails&amp;quot;/&amp;gt;&lt;br /&gt;
    &amp;lt;toss result=&amp;quot;heads&amp;quot;/&amp;gt;&lt;br /&gt;
 ''   ...etc....''&lt;br /&gt;
 &amp;lt;/tosses&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now carefully consider the following two location paths into this document, each using a stacked predicate:&lt;br /&gt;
&lt;br /&gt;
 (//toss)[@result=&amp;quot;heads&amp;quot;][3]&lt;br /&gt;
 (//toss)[3][@result=&amp;quot;heads&amp;quot;]&lt;br /&gt;
&lt;br /&gt;
See the difference? The first path locates (a) all &amp;lt;tt&amp;gt;toss&amp;lt;/tt&amp;gt; elements whose &amp;lt;tt&amp;gt;result&amp;lt;/tt&amp;gt; attribute equals &amp;quot;heads,&amp;quot; and then (b) the third one of those &amp;lt;tt&amp;gt;toss&amp;lt;/tt&amp;gt; elements. Therefore, in the above document, it selects the fourth &amp;lt;tt&amp;gt;toss&amp;lt;/tt&amp;gt; element in the document.&lt;br /&gt;
&lt;br /&gt;
The second path, though, starts out by selecting the third &amp;lt;tt&amp;gt;toss&amp;lt;/tt&amp;gt; element; the stacked predicate applies a further screen, selecting the third &amp;lt;tt&amp;gt;toss&amp;lt;/tt&amp;gt; element only if its &amp;lt;tt&amp;gt;result&amp;lt;/tt&amp;gt; attribute has a value of &amp;lt;tt&amp;gt;heads&amp;lt;/tt&amp;gt;. Because the third &amp;lt;tt&amp;gt;toss&amp;lt;/tt&amp;gt; element's &amp;lt;tt&amp;gt;result&amp;lt;/tt&amp;gt; attribute is &amp;lt;tt&amp;gt;tails&amp;lt;/tt&amp;gt;, therefore, this location path returns an empty node-set.&lt;br /&gt;
&lt;br /&gt;
Also note in these two examples the use of parentheses to isolate a portion of a location path from a predicate. This enables the XPath to apply the predicate(s) to the parenthetical portion as a whole, rather than just to the last location step in the path.&lt;br /&gt;
&lt;br /&gt;
== Compound Location Paths Revisited ==&lt;br /&gt;
&lt;br /&gt;
Early in this chapter, I mentioned that you could join together multiple location paths into a single one, using the &amp;quot;pipe&amp;quot; character, &amp;lt;tt&amp;gt;|&amp;lt;/tt&amp;gt;. In that section, you saw this example:&lt;br /&gt;
&lt;br /&gt;
 /customers/customer/invoice | /customers/customer/cust_info&lt;br /&gt;
&lt;br /&gt;
For any given location path, you could say that any given location ''step'' shifts the context in which succeeding location steps are evaluated. Thus, for the first location path in this compound location path, the context is narrowed first to the root &amp;lt;tt&amp;gt;customers&amp;lt;/tt&amp;gt; element (thereby excluding from consideration any content in the document that precedes or follows the root element), then to &amp;lt;tt&amp;gt;customer&amp;lt;/tt&amp;gt; children of the root element, and finally to &amp;lt;tt&amp;gt;invoice&amp;lt;/tt&amp;gt; children of those &amp;lt;tt&amp;gt;customer&amp;lt;/tt&amp;gt; children.&lt;br /&gt;
&lt;br /&gt;
What, you might reasonably wonder, happens to the context in succeeding location paths of a compound location path? Every constituent location path is considered independently — just as if it were the ''only'' location path. Obviously, if the location path is absolute (as in the example from early in the chapter just repeated here), its context node is immaterial. If the location path is relative, it is evaluated relative to whatever the context node is at that point, ''disregarding'' any shifts in context effected by preceding portions of the compound location path. Consider this example:&lt;br /&gt;
&lt;br /&gt;
 invoice | cust_info&lt;br /&gt;
&lt;br /&gt;
The first location path selects all &amp;lt;tt&amp;gt;invoice&amp;lt;/tt&amp;gt; children of the context node for the compound location path as a whole. Likewise, the second selects all &amp;lt;tt&amp;gt;cust_info&amp;lt;/tt&amp;gt; children of the context node for the compound location path as a whole — ''not'' all &amp;lt;tt&amp;gt;cust_info&amp;lt;/tt&amp;gt; children of the &amp;lt;tt&amp;gt;invoice&amp;lt;/tt&amp;gt; elements selected by the first location path. The results of the two selections are simply unioned together into a single node-set.&lt;br /&gt;
&lt;br /&gt;
Along these lines, also note that each constituent location path may employ &amp;quot;stacked&amp;quot; predicates (as discussed earlier in the chapter), compound predicates, or any other location path variations. Predicates used in location path A have no effect on those in location path B and vice versa.&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Docbook2Wiki</name></author>	</entry>

	</feed>