XPath cheat sheet (external link): [1] - covers XPath 1.0.
XPath 2.0 in expecco
Since release 26.2, expecco's XPath implementation (XML::XPathParser) also understands XPath 2.0. The examples below were evaluated against this document:
<books>
<book id="b1" year="2001"><title>Alpha</title><price>12.50</price></book>
<book id="b2" year="2010"><title>Beta</title><price>8</price></book>
</books>
Sequences
| Expression |
Result
|
(1, 2, 3) |
(1, 2, 3)
|
() |
the empty sequence
|
1 to 5 |
(1, 2, 3, 4, 5)
|
//book/(title, price) |
title and price of every book, in document order
|
//book/title/string() |
("Alpha", "Beta")
|
//book/xs:decimal(price) |
(12.50, 8)
|
Control
| Expression |
Result
|
if (count(//book) > 1) then "many" else "one" |
"many"
|
for $b in //book return $b/title/string() |
("Alpha", "Beta")
|
some $p in //price satisfies $p > 10 |
true
|
every $b in //book satisfies $b/@year >= 2000 |
true
|
Node sets and comparisons
| Expression |
Result
|
//book[1] union //book[2] |
both books
|
//book except //book[@id="b1"] |
the second book
|
//book intersect //book[price > 10] |
the first book
|
1 eq 1 |
true (value comparisons: eq ne lt le gt ge)
|
//book[1] is //book[1] |
true (same node)
|
//book[1] << //book[2] |
true (document order; also >>)
|
10 idiv 3 |
3
|
Types
| Expression |
Result
|
"42" castable as xs:integer |
true
|
"42" cast as xs:integer |
42
|
3 instance of xs:integer |
true
|
//book[1] instance of element(book) |
true
|
//element(title) |
all title elements (kind test as a step)
|
//book/attribute(id) |
the id attributes
|
Sequence and aggregate functions
| Expression |
Result
|
sum(//price) |
20.5
|
avg(//price) |
10.25
|
max(//book/@year) |
2010
|
distinct-values((1, 2, 1)) |
(1, 2)
|
reverse(1 to 3) |
(3, 2, 1)
|
subsequence(1 to 10, 3, 2) |
(3, 4)
|
index-of((5, 6, 5), 5) |
(1, 3)
|
empty(()) |
true
|
exists(//book) |
true
|
Strings and regular expressions
| Expression |
Result
|
upper-case("abc") |
"ABC"
|
ends-with("file.xml", ".xml") |
true
|
string-join(//title, "; ") |
"Alpha; Beta"
|
matches("Hello", "^h", "i") |
true (flags: i m s x)
|
replace("2026-11-09", "(\d+)-(\d+)-(\d+)", "$3.$2.$1") |
"09.11.2026"
|
tokenize("a,b,,c", ",") |
("a", "b", "", "c")
|
Numbers
| Expression |
Result
|
abs(-3) |
3
|
round(2.5) |
3
|
round(-2.5) |
-2 (halves round upwards)
|
round-half-to-even(2.5) |
2
|
Dates, times and durations
| Expression |
Result
|
xs:date("2026-11-09") + xs:yearMonthDuration("P1M") |
2026-12-09
|
xs:dateTime("2026-11-09T12:00:00Z") - xs:dateTime("2026-11-01T00:00:00Z") |
P8DT12H
|
xs:dayTimeDuration("PT90M") |
PT1H30M
|
hours-from-duration(xs:dayTimeDuration("PT90M")) |
1
|
year-from-date(xs:date("2026-11-09")) |
2026
|
timezone-from-dateTime(xs:dateTime("2026-11-09T12:00:00+01:00")) |
PT1H
|
adjust-dateTime-to-timezone(xs:dateTime("2026-11-09T12:00:00Z"), xs:dayTimeDuration("PT1H")) |
2026-11-09T13:00:00+01:00
|
current-date() instance of xs:date |
true
|
Documents (local files)
| Expression |
Result
|
doc("file:///home/me/books.xml")//title |
the titles of another document
|
doc-available("file:///home/me/books.xml") |
true if it exists and is well-formed
|
collection("file:///home/me/data/")//book |
the books of all *.xml files of a directory
|
resolve-uri("data/a.xml", "file:///home/me/") |
"file:///home/me/data/a.xml"
|
base-uri(.) |
the URI of the context node (xml:base aware)
|
idref("b1") |
the IDREF attributes referring to id b1 (needs a DTD)
|
Not supported
- schema-aware types (only the built-in xs: types), collations, and the Unicode normalization forms NFKC/NFKD of
normalize-unicode().
doc(), collection() and friends read local files (file: URIs) only.