Path Expressions

Basic Syntax

AAll <A> nodes within the current context, i.e. relative to the current path.
/AThe <A> root node, i.e. an absolute path.
//AAll <A> nodes in the document, regardless of how deeply nested they are.
.The current context, i.e. the current node.
..The parent context, i.e. the parent node.
A/BAll <B> nodes that are the direct children of <A> nodes within the current context.
A//BAll <B> nodes that are the descendants of <A> nodes within the current context.
A/*All nodes that are the direct children of <A> nodes within the current context.
@AThe A attribute of the current context/node. (An attribute may be treated as the child of its node.)
@*All attributes of the current context/node.
N:AAll <A> child nodes from the N namespace within the current context.
N:*All nodes from the N namespace within the current context.
*:AAll <A> nodes from all namespaces within the current context.
A[B]All <A> nodes containing a <B> child node.
A[@B]All <A> nodes containing the attribute B.
A/@BAll B attributes in <A> within the current context.
A[3]The third <A> node within the current context.
A[B][3]The third <A> node containing a <B> child within the current context.
(A/B)[3]The third <B> node that is a child of an <A> node within the current context.
A/text()[2]The second text node in each <A> node within the current context.
A|BAll <A> and <B> child nodes within the current context.

The square brackets [] at the right can hold a Boolean value, an integer, or a node. A complex Boolean expression joined by and/or can be formed out of these three types of values.


Axes

child::*
descendant::*
descendant-or-self::*
self::*
following::*
following-sibling::*
ancestor::*
ancestor-or-self::*
parent::*
preceding::*
preceding-sibling::*
namespace::*
attribute::*

* matches only element nodes. If node() is used instead, text, comment, and processing-instruction nodes are matched as well. Multiple nodes may be returned — for example, preceding-sibling::node()[2] returns the previous node that is two siblings away. Any derived type of node() can be used in place of node(), e.g. child::comment().


Complex Filters

A[position()<3]The first two <A> nodes.
A[last()]The last <A> child node.
A[B][C]All <A> nodes containing a <B> node and a <C> node.
A[(B or C) and D]All <A> nodes containing a <D> node, and a <B> node or a <C> node.
A[not(B)]All <A> nodes which do not contain a <B> node.
A[B="C"]All <A> nodes containing <B> nodes with the value C.
A[.!="B"]All <A> nodes with a value that is not "B".
(B|C)[@at eq A/@at]All <B> nodes and <C> nodes whose attribute @at equals that of <A>.

Examples

The examples below evaluate expressions against this sample document:
<?xml version="1.0"?>
<menu restaurant="Golden Outlet">
  <dish id="1">Satay <i>Cooked</i></dish>
  <drink id="2">Cola</drink>
  <dish id="3">Curry Chicken</dish>
  <dish id="4" xmlns="http://example.com">Sweet and Sour Pork</dish>
</menu>

Each of the following returns the document node (the whole document):
.
/.
self::node()
/self::node()
let $p := /. return $p
menu/..
menu!..
root()
root(menu/drink)
doc('menu.xml')

Each of the following returns the <menu> root element:
menu
/menu
menu[1]
menu[@restaurant]
menu[@restaurant="Golden Outlet"]
menu[drink]
menu[drink="Cola"]
menu[drink][dish]
child::node()
node()
menu[last()]|menu[position()=1]|menu[1]
if (//dish) then menu else //dish

Each of the following returns the attribute restaurant="Golden Outlet":
/menu/@restaurant
menu//@restaurant
//@restaurant
(//@*)[1]
(//attribute::node())[1]
//attribute(restaurant)

Each of the following selects among the <dish> nodes, returning <dish id="1">Satay <i>Cooked</i></dish> and/or <dish id="3">Curry Chicken</dish>:
//dish
menu/dish
//dish[1] | //dish[2]
//dish[1] union //dish[2]
//dish[position()=(1,2)] intersect //dish
/menu/child::node()[@id] except /menu/child::node()[@id=2 or @id=4]
/menu/dish[@id]
/menu/dish[@id<10]
/menu/dish[@id=1 or @id=3]
/menu/dish[@id=1]|//dish[@id=3]
menu/child::node()[@id!=2 and not(@id=4)]
menu/dish[i]|menu/dish[.="Curry Chicken"]
/menu/element(dish)

//i/text(), (//text()[1])[3], /menu/dish/*/text(), and /menu[1]/dish[1]/i[1]/text() all return the text node Cooked.

/menu/dish[2]/following::node() returns, in order: a whitespace text node, the <dish id="4" xmlns="http://example.com"> element, its text content Sweet and Sour Pork, and a trailing whitespace text node.

Each of the following returns true:
//dish[1] is //dish[@id=1]
//dish[2] >> //dish[@id=1]
//dish[@id=1] << //dish[2]
some $x in //dish satisfies $x[@id>0]
every $x in //dish satisfies $x[@id>0]
count(/menu/child::node()) > count(/menu/child::*)
not(. instance of element())
menu instance of element()
menu instance of element(menu)

menu/dish/string-length() returns 12 (the length of "Satay Cooked"); ('abcdefghijkl', 'xmnopqrstuvwx')!string-length() returns (12, 13).

ch03-menu.xml:
<?xml version="1.0"?>
<menu restaurant="Golden Outlet">
   <dish id="1">Satay <i>Cooked</i></dish>
   <drink id="2">Cola</drink>
   <dish id="3">Curry Chicken</dish>
   <dish id="4" xmlns="http://example.com">Sweet and Sour Pork</dish>
</menu>

ch03-path-expression.xpath.txt:
//dish[@id=1 or @id=3]

Satay Cooked Curry Chicken