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

XPath Axes and Functions

Axes such as ancestor and following-sibling, string and number functions, position(), and what XPath 2.0 and 3.1 add.

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

Axes

A step can move in any direction from the current node with an axis: axis::node-test[predicate].

Axis Direction
child:: (default), attribute:: (@) down one level, attributes
descendant::, descendant-or-self:: (//) everything below
parent:: (..), ancestor:: up
following-sibling::, preceding-sibling:: sideways, same parent
following::, preceding:: after / before in document order
self:: (.) the node itself

Functions

  • Strings: concat(), contains(), starts-with(), substring(), substring-before(), string-length(), normalize-space(), translate() (XPath 1.0's way to change case).
  • Numbers: sum(), count(), round(), floor(), ceiling(), number().
  • Nodes: position(), last(), name(), local-name(), namespace-uri(), not().
Axes, strings and positionsTry 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>""")
q = shop.xpath

print(q("//name[.='Camel mug']/../@category")[0])                       # parent, then attribute
print(q("//product[@sku='MUG-07']/following-sibling::product/@sku"))    # siblings after
print(q("//price[. > 20]/ancestor::product/name/text()"))              # up to the product
print(q("//product[contains(name, 'tea') or starts-with(@sku, 'COF')]/@sku"))
print(q("translate(string(//product[1]/name), 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')"))
print(q("concat(count(//product[stock > 0]), ' of ', count(//product), ' in stock')"))
print(q("//product[position() <= 2]/@sku"))

Output

kitchen
['PAN-03']
['Frying pan']
['TEA-01', 'COF-02']
GREEN TEA
3 of 4 in stock
['TEA-01', 'COF-02']

XPath 2.0 and 3.1

Later versions (supported by Saxon, not by libxml2, browsers or the JDK's built-in engine) add typed sequences, if … then … else, for … return, regular expressions (matches(), replace()), dates, string-join(), and in 3.1 maps, arrays and JSON. In Python you can use elementpath or saxonche for XPath 3.1; the XQuery page shows the newer syntax.

Test yourself

Which axis selects elements that come after the current node and share its parent?

  1. following-sibling::
  2. following::
  3. descendant::
  4. ancestor::
Show answer

Answer: following-sibling::

following:: includes everything later in the document; following-sibling:: only the same parent's children.

Was this page helpful?