Skip to main content

Search 400 pages — tools, formats, elements, namespaces, directory, comparisons, XPath, datatypes, glossary, parse errors, schema errors, use cases, guides, blog and product.

XPath guide

XPath predicates, position(), and parentheses

Predict which node set an XPath predicate filters, distinguish numeric from boolean predicates, and select the first match at the intended scope.

8 min read · Updated 2026-08-21

The short answer

A predicate filters the node set produced by the step immediately before it. A numeric predicate such as [1] keeps nodes whose proximity position is 1, while a boolean predicate keeps nodes for which its expression is true. Parenthesize a complete path before [1] when you mean the first result overall rather than the first matching child under each parent.

Identify the node set being filtered

XPath evaluates an axis and node test, then applies its predicates in order. The context position and size are recalculated for the current node set, so moving brackets or parentheses changes the question even when the same tokens remain visible.

First matching child for each parent
//section/item[1]
First matching item in the document result
(//section/item)[1]

Separate numeric and boolean predicate semantics

The predicate [2] is positional: it is shorthand for [position() = 2]. A string or node-set expression is converted to boolean instead, so [price] keeps nodes that have a price child and [price='10'] keeps nodes with a matching value.

  • Use [n] for a proximity position in the current axis order.
  • Use [child] to require that child node set to be non-empty.
  • Use [condition][position] when the position should apply after filtering.
  • Remember that reverse axes have reverse proximity positions.
Second available item
//item[@available='true'][2]
Available item that is second among siblings
//item[2][@available='true']

Test scope with multiple parents and near misses

A one-parent sample cannot reveal whether [1] is applied per parent or globally. Add at least two parents, missing children, and non-matching siblings, then compare the selected node paths rather than only the returned text values.

Use last() only after deciding the current set. //section/item[last()] returns the last item under each section; (//section/item)[last()] returns the last item in the combined path result.

Get started

Bring order to the XML your team can't afford to ignore.

Create a free account and get a private workspace to search, validate, diff, and monitor your XML feeds, sitemaps, schemas, and vendor integrations.