Chapter 55: XPath Examples
XPath Examples tutorial — written as if I’m your personal teacher sitting next to you, whiteboard ready, explaining slowly and clearly, with lots of drawings, step-by-step reasoning, many small-to-realistic examples, common mistakes people make, “try this yourself” exercises, and real-world context.
We will start from the very simplest expressions and gradually build up to more powerful and useful ones.
Preparation: The XML document we will use in almost all examples
Save this small but realistic XML as library.xml (or paste it as a string when you test):
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
<?xml version="1.0" encoding="UTF-8"?> <library owner="Alice" city="Hyderabad"> <!-- Popular books section --> <book id="b1" year="2018" lang="en" category="self-help" inStock="true"> <title>Atomic Habits</title> <author>James Clear</author> <price currency="INR">499.00</price> <stock>45</stock> </book> <book id="b2" year="1997" lang="en" category="finance" inStock="false"> <title>Rich Dad Poor Dad</title> <author>Robert Kiyosaki</author> <price currency="INR">349.00</price> <stock>12</stock> </book> <book id="b3" year="2003" lang="en" category="fiction" inStock="true"> <title>The Alchemist</title> <author>Paulo Coelho</author> <price currency="USD">12.99</price> <stock>0</stock> </book> <magazine id="m1"> <title>India Today</title> <issue>July 2025</issue> <price currency="INR">120.00</price> </magazine> </library> |
Example 1 – The absolute simplest XPath expressions
1.1 Select all <title> elements
//title→ Returns 4 nodes:
- Atomic Habits
- Rich Dad Poor Dad
- The Alchemist
- India Today
1.2 Select only book titles
//book/title→ Returns 3 nodes (magazine title is excluded)
1.3 Select the title of the first book only
//book[1]/titleor
(//book/title)[1]→ “Atomic Habits”
Important difference (very common confusion):
//book[1]/title → title of the first book child of any parent
(//book/title)[1] → the very first title in document orderIn this case both give the same result, but in larger documents they can differ.
Example 2 – Using attributes in conditions
2.1 Select books published in 2018
//book[@year = "2018"]→ returns the Atomic Habits book
2.2 Select books in English
//book[@lang = "en"]→ returns all three books
2.3 Select books that are in stock
//book[@inStock = "true"]→ Atomic Habits + The Alchemist
2.4 Select books that are not in stock
//book[@inStock != "true"]or better:
//book[not(@inStock = "true")]→ Rich Dad Poor Dad
Example 3 – Numeric comparisons
3.1 Select books cheaper than 400 INR
//book[price[@currency="INR"] and number(price) < 400]→ Rich Dad Poor Dad (349)
3.2 Select books more expensive than 400 INR
//book[number(price) > 400]→ Atomic Habits (499)
Important note: number(price) is necessary because price is text — without it, “499” is compared as string.
Example 4 – Combining conditions with and / or
4.1 Books that are cheap AND in stock
//book[number(price) < 400 and @inStock = "true"]→ (none in our document)
4.2 Books that are either cheap OR old (before 2000)
//book[number(price) < 400 or @year < 2000]→ Rich Dad Poor Dad (cheap + old)
4.3 Books that are not in stock
//book[not(@inStock = "true")]or
//book[@inStock != "true"]Example 5 – Using position() and last()
5.1 Select the second book
(//book)[2]→ Rich Dad Poor Dad
5.2 Select the last book
//book[last()]→ The Alchemist
5.3 Select every second book (odd positions)
//book[position() mod 2 = 1]→ book 1 + book 3 (Atomic Habits + The Alchemist)
Example 6 – Using text() and string functions
6.1 Select books whose title contains “Dad”
//book[contains(title, "Dad")]→ Rich Dad Poor Dad
6.2 Select books whose title starts with “The”
//book[starts-with(title, "The")]→ The Alchemist
6.3 Select books whose title does not contain “Habits”
//book[not(contains(title, "Habits"))]→ Rich Dad Poor Dad + The Alchemist
Example 7 – Combining multiple conditions (realistic filtering)
7.1 Books that are:
- in English
- published after 2000
- cost less than 1000 INR
- in stock
//book[
@lang = "en" and
@year > 2000 and
price[@currency="INR" and number(.) < 1000] and
@inStock = "true"
]→ Atomic Habits (only one matches all conditions)
Example 8 – Try yourself exercises (do these!)
- Select all prices that are in INR
- Select the title of the second book
- Select books cheaper than 400 INR
- Select books published after 2000
- Select all author names
- Select the last book in the document
- Select books that are not in stock and cost more than 300 INR
- Select books whose title contains “Dad” or starts with “A”
- Select books that have a price and are in stock
- Select the third element that is a child of <library>
Summary – XPath Operators Quick Reference
| Operator | Purpose | Example XPath | Tip / Common mistake |
|---|---|---|---|
| = | equals | @year = 2018 | Case-sensitive for strings |
| != | not equals | @inStock != “true” | Works for strings too |
| < > <= >= | numeric comparison | number(price) < 500 | Use number() — otherwise string comparison |
| and | both true | @year > 2000 and price < 1000 | Use parentheses when combining |
| or | at least one true | @category=”fiction” or @category=”self-help” | Use parentheses when mixing with and |
| not() | logical NOT | not(@inStock = “true”) | not() is a function — needs parentheses |
| + – * div mod | arithmetic | price * 1.18 | div for division (not /) |
|
union (combine node-sets) | `//book/title |
Would you like to continue with one of these next?
- Very deep dive into comparison operators (strings vs numbers, case sensitivity, number(), string())
- Complex logical conditions – combining and/or/not with parentheses
- Arithmetic inside predicates – calculating totals, discounts, GST…
- The pipe operator – combining different branches
- XPath functions that work with operators (contains, starts-with, normalize-space, count, sum…)
- Real-world examples — e-invoice filtering, RSS item selection, SOAP payload checks
Just tell me which direction feels most useful or interesting for you right now! 😊
