What XPath is

XPath (XML Path Language) is a query language for addressing parts of an XML document. Where SQL selects rows from tables, XPath selects nodes from a document tree — elements, attributes, text, comments. An XPath expression describes a path through the tree and, optionally, conditions that the matching nodes must satisfy. The result is a node-set (or, for some expressions, a string, number, or boolean).

XPath is everywhere XML is processed: it is the selection language inside XSLT, it powers element location in Selenium and Playwright, and it is exposed by XML libraries in Python (lxml), Java, .NET, and the browser. Learning it once pays off across all of them.

A sample document

Every example below runs against this catalog:

<catalog>
  <book id="bk101" category="tech">
    <title>XML Developer's Guide</title>
    <author>Gambardella</author>
    <price>44.95</price>
  </book>
  <book id="bk102" category="fiction">
    <title>Midnight Rain</title>
    <author>Ralls</author>
    <price>5.95</price>
  </book>
</catalog>

The expressions you use most

Expression Selects
/catalog/bookAll book elements that are direct children of the root catalog
//bookEvery book element anywhere in the document
//book/titleThe title of every book
//book/@idThe id attribute of every book
//book[1]The first book (XPath is 1-indexed, not 0)
//book[@id='bk101']The book whose id is bk101
//book[price>10]Books whose price child is greater than 10
//book[last()]The last book in the set
//title/text()The text content of every title
count(//book)A number — how many books exist

Paths, predicates, and axes

An XPath expression is a series of steps separated by /. Each step has an axis (which direction to look), a node test (what to match), and zero or more predicates (conditions in square brackets). The single slash / means "direct child"; the double slash // is shorthand for the descendant axis — "at any depth below."

Predicates filter a node-set. //book[@category='fiction'] keeps only books whose category attribute equals fiction. Predicates can stack and can contain functions: //book[price>10][position()=1].

Axes let you move in directions other than down. Beyond the default child axis, the most useful are parent::, ancestor::, following-sibling::, and attribute:: (which @ abbreviates). For example, //title[text()='Midnight Rain']/parent::book/@id walks from a title back up to its book and reads the id.

The namespace gotcha

The single most common reason an XPath "returns nothing" on real-world documents is namespaces. If your XML declares a default namespace — <feed xmlns="http://www.w3.org/2005/Atom"> — then //entry matches nothing, because entry is now in that namespace, not the empty one.

In a full engine you bind a prefix and query //atom:entry. A quick workaround that needs no namespace setup is to match by local name: //*[local-name()='entry']. It's verbose but reliable when you just need to extract data fast.

XPath 1.0 vs 2.0/3.1

Browsers — and therefore most online testers — implement XPath 1.0 via document.evaluate(). XPath 2.0 and 3.1 add a type system, sequences, regular-expression functions, and conditional expressions, but they require a dedicated engine like Saxon and aren't available natively in the browser. The good news: the selection and filtering tasks most people reach for — navigate, filter by attribute or value, count, extract text — are all fully covered by 1.0.

Testing XPath against your own XML

The fastest way to learn XPath is to run expressions against a real document and watch what matches. An online tester parses your XML, evaluates the expression with document.evaluate(), and lists the matching nodes and their values — all client-side, so your data never leaves the browser. That tight loop (tweak expression → see matches) is how the table above becomes second nature.

Test XPath expressions now

Paste your XML, type an XPath expression, and see every matching node instantly. Runs entirely in your browser — nothing is uploaded.

Open XPath Tester →

Frequently Asked Questions

What is XPath used for?

XPath is a query language for selecting nodes in an XML document — extracting values, navigating between elements and attributes, and filtering by condition. It underpins XSLT, browser automation tools like Selenium, and XML libraries in nearly every language.

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

A single slash selects a direct child at that step, so /catalog/book selects books that are direct children of catalog. A double slash selects descendants at any depth, so //book selects every book element anywhere in the document.

How do I select an attribute with XPath?

Prefix the attribute name with @. //book/@id selects the id attribute of every book, and //book[@id='bk101'] selects books whose id equals bk101. The square brackets hold a predicate that filters by condition.

Why does my XPath return no results?

The usual cause is namespaces. If the document declares a default namespace, an unprefixed name like //entry won't match. Either bind a prefix and query //ns:entry, or match by local name with //*[local-name()='entry'].

Which XPath version do browsers support?

Browsers implement XPath 1.0 through document.evaluate(). XPath 2.0 and 3.1 add types, sequences, and many functions but require a dedicated engine such as Saxon and are not available natively in the browser. Most selection and filtering only needs 1.0.