XML Tutorial · XPath, XSLT and XQuery · Lesson 12 of 28

XPath Basics

Selecting nodes with XPath: paths, the // shortcut, attributes, predicates, and the core functions.

Create a free account to save this page, take notes and track your progress. Sign in

Paths through the tree

XPath is a small language for pointing at parts of an XML document, like file paths for a tree. XPath 1.0 is built into lxml, PHP, Java and every browser.

Expression Selects
/shop/product product children of the root shop
//name every name element anywhere
//product/@sku the sku attribute of every product
//product[price > 10] products whose price is over 10
//product[@category='drinks']/name names of products in a category
//product[1] the first product of each parent (positions start at 1)
//product[last()] the last one
count(//product) a number
. / .. the current node / its parent
* / @* / text() any element / any attribute / text nodes

The same queries in three languages

Query a product listTry it yourself
from lxml import etree

shop = etree.fromstring(b"""<shop>
  <product sku="TEA-01" category="drinks"><name>Green tea</name><price>3.50</price><stock>40</stock></product>
  <product sku="COF-02" category="drinks"><name>Coffee beans</name><price>9.90</price><stock>0</stock></product>
  <product sku="MUG-07" category="kitchen"><name>Camel mug</name><price>12.00</price><stock>15</stock></product>
  <product sku="PAN-03" category="kitchen"><name>Frying pan</name><price>29.00</price><stock>4</stock></product>
</shop>""")

print("products:", int(shop.xpath("count(//product)")))
print("over 10:", shop.xpath("//product[price > 10]/name/text()"))
print("drinks:", shop.xpath("//product[@category='drinks']/@sku"))
print("out of stock:", shop.xpath("string(//product[stock = 0]/name)"))
print("total stock:", int(shop.xpath("sum(//stock)")))

Output

products: 4
over 10: ['Camel mug', 'Frying pan']
drinks: ['TEA-01', 'COF-02']
out of stock: Coffee beans
total stock: 59

Common mistakes

  • // searches the whole document from the root; inside a loop use .//name (relative to the current node).
  • //product[1] is "the first product of each parent", not "the first product in the document": use (//product)[1] for that.
  • Comparing a node set with a value is true if any node matches, so //price != 3.50 is true almost always.
  • Namespaced documents need prefixes in every step; see namespaces.

Test yourself

Which XPath selects the very first product in the whole document?

  1. (//product)[1]
  2. //product[1]
  3. /product[0]
  4. //product[first()]
Show answer

Answer: (//product)[1]

//product[1] picks the first product child of each parent; parentheses apply the position to the whole set.

Was this page helpful?