XPath Reference

XPath 1.0 and 2.0 axes, functions and expressions in a searchable table

Searchable XPath reference covering node-selection axes (child, descendant, ancestor, following-sibling), predicates, location-path syntax and the most-used built-in functions across XPath 1.0 and 2.0. It runs free in your browser on Gera Tools, with nothing uploaded.

Last updated Source: Gera Tools

What is the difference between / and // in XPath?

A single slash / selects from the immediate children of the context node, so /html/body selects body only if it is a direct child of html. A double slash // is shorthand for the descendant-or-self axis, so //div selects div elements at any depth below the context.

XPath is the expression language for addressing parts of an XML (or HTML) document. It is the backbone of XSLT, XQuery and most browser/automation element selectors. An XPath is a sequence of steps, each navigating an axis from a context node and optionally filtered by predicates. This reference lists the axes, syntax and the functions you reach for most often.

How it works

A location path is a series of steps separated by /. Each step has the form axis::node-test[predicate]. Starting from a context node, the engine moves along the named axis (e.g. child, descendant, following-sibling), keeps nodes matching the node test (an element name, *, text(), @attr), then filters with any predicates. Steps compose to walk the tree precisely. Abbreviations make common paths short: // is descendant-or-self::, @ is attribute::, . is the context node and .. is the parent.

The axes at a glance

Each axis defines a direction of travel from the current context node. The most commonly used ones are:

AxisWhat it selects
childDirect child nodes (the default axis; child::p and p are equivalent)
descendantAll descendants, any depth
descendant-or-selfDescendants plus the context node itself (abbreviated //)
parentThe single immediate parent
ancestorAll ancestors up to the root
following-siblingSiblings that appear after the context node
preceding-siblingSiblings that appear before it
attributeAttributes of the context element (abbreviated @)
selfThe context node itself (abbreviated .)

Worked examples

//div[@class='item']           every div whose class attribute is exactly "item"
//ul/li[1]                     the first li child of each ul element
//a[contains(@href,'pdf')]     anchors whose href contains the string "pdf"
//input[@type='text']/..       the parent element of each text input
count(//tr)                    number of tr elements in the whole document
//p[not(contains(@class,'hidden'))]    paragraphs that do not have class "hidden"
//table[2]//td[last()]         last cell in every row of the second table
//*[@id='main']/following-sibling::*   all elements after the one with id="main"

Predicates in depth

Predicates filter within square brackets. They can test attributes, position, text content, or any XPath expression that evaluates to a boolean or number. A few patterns worth memorising:

  • [1] and [last()] — positional; XPath counts from 1, not 0.
  • [@attr] — tests that the attribute exists, regardless of value.
  • [@attr='value'] — exact attribute match.
  • [contains(text(),'word')] — substring match on the text content.
  • [normalize-space()='exact phrase'] — trims whitespace before matching.
  • [position() mod 2 = 0] — even-positioned nodes (for striped table rows).

Predicates can be chained: //tr[@class='row'][position() > 2] selects class-row rows that are not the first two.

Notes and tips

XPath indexes from 1, not 0 — [1] is the first node. A bare text() returns the text node, while string(.) returns the concatenated string value of an element. Prefer normalize-space() when matching text to ignore surrounding whitespace. XPath 1.0 is what browsers and Selenium use; reach for Saxon when you need 2.0+ features like matches(), tokenize() and sequences.

When targeting HTML with browser automation (Playwright, Selenium), // paths starting from the document root can be slow on large pages because they scan every node. Anchor your path to a known ID or landmark first — //div[@id='results']//li is faster than //li — and prefer CSS selectors for simple class or ID lookups, saving XPath for cases where you genuinely need an axis (like selecting a parent) or a function (like contains).