XPath Tester

Test XPath expressions against XML and see all matching nodes

Try an example

XML Input

Runs locally · Safe to paste secrets

What is XPath?

XPath (XML Path Language) is a query language for selecting nodes from an XML document. Defined by the W3C as part of the XSLT standard, XPath treats an XML document as a tree of nodes and provides a path-based syntax for navigating that tree. An XPath expression like //book[@category="fiction"]/title selects every title element inside a book element whose category attribute equals "fiction". XPath 1.0, the version supported by all major browsers and most XML libraries, was published as a W3C Recommendation in 1999 and remains the most widely deployed version.

XPath expressions return one of four result types: node sets, strings, numbers, or booleans. A node set is the most common result and contains zero or more XML nodes (elements, attributes, text nodes, comments, or processing instructions). String, number, and boolean results come from XPath functions like count(), sum(), contains(), and boolean comparisons. This type system makes XPath suitable both for extracting data and for writing conditional logic in XSLT stylesheets and XML Schema assertions.

Version 1.0 expressions work everywhere: JavaScript's document.evaluate(), Python's lxml and ElementTree, Java's javax.xml.xpath, PHP's DOMXPath, and command-line tools like xmllint. Versions 2.0 and 3.1 add richer type systems and functions but require dedicated engines like Saxon. Use Version 1.0 by default. Reach for 2.0 or 3.1 only when you need sequences, regular expressions, or higher-order functions — and accept the dependency on Saxon or BaseX.

Why Use an Online XPath Tester?

Writing correct expressions requires understanding the document structure and testing against real data. The tool gives you an interactive environment to iterate on expressions without setting up a project or writing boilerplate code.

Test expressions instantly
Paste your XML, type an expression, and see matching nodes in real time. No compilation step, no REPL setup, no dependencies to install.
🔒
Privacy-first processing
All XML parsing and query evaluation runs in your browser using the native DOMParser and document.evaluate() APIs. Your XML data never leaves your machine.
🔍
Debug complex queries step by step
Break down long expressions by testing each axis and predicate individually. See exactly which nodes match at each step to isolate errors.
📋
Copy results for documentation
Copy matched nodes or scalar results with one click. Useful for pasting into bug reports, test assertions, or data extraction scripts.

XPath Tester Use Cases

Frontend developer
Test XPath selectors for SVG manipulation or XML-based configuration before embedding them in JavaScript code that calls document.evaluate().
Backend engineer
Validate queries against SOAP responses or XML API payloads before writing extraction logic in Python, Java, or Go.
DevOps / Infrastructure
Query XML configuration files (Maven pom.xml, Spring beans, CI pipeline configs) to extract dependency versions or verify settings without editing the files.
QA / Test automation
Build and verify XPath locators for Selenium or Playwright before adding them to test scripts. Test edge cases like missing attributes or namespace prefixes.
Data engineer
Prototype queries for XML data feeds (RSS, Atom, XBRL financial reports) before wiring them into ETL pipelines.
Student / learner
Experiment with XPath axes, predicates, and functions using sample XML. See results immediately to build intuition for tree traversal patterns.

XPath Axes Reference

An axis defines the direction of navigation relative to the current (context) node. The full syntax is axis::node-test[predicate], though most developers use the abbreviated forms (//, @, ..) daily. This table lists all 1.0 axes with practical examples.

AxisExampleDescription
childchild::bookDirect children named "book"
descendantdescendant::titleAll "title" elements at any depth
parentparent::*The parent of the current node
ancestorancestor::catalogAll ancestors named "catalog"
following-siblingfollowing-sibling::bookSiblings after the current node
preceding-siblingpreceding-sibling::bookSiblings before the current node
attributeattribute::langThe "lang" attribute of the node
selfself::bookThe current node if it is "book"
descendant-or-self//titleShorthand: any "title" in the tree
ancestor-or-selfancestor-or-self::*Current node plus all ancestors

XPath 1.0 Functions

The language defines 27 built-in functions across four categories: node set, string, number, and boolean. These are the functions you will use most often when writing queries. All are supported by this tester and by every compliant implementation.

FunctionCategoryDescription
text()Node testSelects text content of a node
position()NumericReturns 1-based position in node set
last()NumericReturns size of current node set
count()NumericCounts nodes: count(//book)
contains()Stringcontains(@class, "active") — substring match
starts-with()Stringstarts-with(title, "The") — prefix match
normalize-space()StringStrips leading/trailing whitespace
string-length()NumericReturns character count of a string
sum()Numericsum(//price) — totals numeric values
not()Booleannot(@disabled) — negation
name()StringReturns element or attribute name

Code Examples

These examples show how to evaluate expressions programmatically. Each snippet uses the same catalog.xml structure so you can compare the API differences across languages.

JavaScript (browser)
const xml = `<catalog>
  <book id="1"><title>1984</title><price>7.99</price></book>
  <book id="2"><title>Dune</title><price>12.99</price></book>
</catalog>`

const parser = new DOMParser()
const doc = parser.parseFromString(xml, 'application/xml')

// Select all book titles
const result = doc.evaluate('//book/title', doc, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null)
let node = result.iterateNext()
while (node) {
  console.log(node.textContent) // → "1984", "Dune"
  node = result.iterateNext()
}

// Get a numeric value
const sum = doc.evaluate('sum(//price)', doc, null, XPathResult.NUMBER_TYPE, null)
console.log(sum.numberValue) // → 20.98
Python (lxml)
from lxml import etree

xml = """<catalog>
  <book id="1"><title>1984</title><price>7.99</price></book>
  <book id="2"><title>Dune</title><price>12.99</price></book>
</catalog>"""

tree = etree.fromstring(xml.encode())

# Select elements by attribute
books = tree.xpath('//book[@id="1"]/title/text()')
print(books)  # → ['1984']

# Use predicates with position
first = tree.xpath('//book[1]/title/text()')
print(first)  # → ['1984']

# Boolean check
has_cheap = tree.xpath('boolean(//price[. < 10])')
print(has_cheap)  # → True
Java (javax.xml.xpath)
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.*;
import org.w3c.dom.*;

var factory = DocumentBuilderFactory.newInstance();
var builder = factory.newDocumentBuilder();
var doc = builder.parse(new java.io.File("catalog.xml"));

var xpath = XPathFactory.newInstance().newXPath();

// Select node set
NodeList titles = (NodeList) xpath.evaluate(
    "//book/title", doc, XPathConstants.NODESET
);
for (int i = 0; i < titles.getLength(); i++) {
    System.out.println(titles.item(i).getTextContent());
    // → "1984", "Dune"
}

// Evaluate to number
double total = (double) xpath.evaluate(
    "sum(//price)", doc, XPathConstants.NUMBER
);
System.out.println(total); // → 20.98
CLI (xmllint)
# Select all book titles
xmllint --xpath '//book/title/text()' catalog.xml
# → 1984Dune

# Select by attribute
xmllint --xpath '//book[@id="2"]/title' catalog.xml
# → <title>Dune</title>

# Count nodes
xmllint --xpath 'count(//book)' catalog.xml
# → 2

# Using xmlstarlet for formatted output
xmlstarlet sel -t -v '//book/title' -n catalog.xml
# → 1984
# → Dune

Frequently Asked Questions

What is the difference between XPath 1.0 and XPath 3.1?
Version 1.0 has four data types (node set, string, number, boolean) and 27 functions. Version 3.1 adds sequences, maps, arrays, date/time types, regular expressions, higher-order functions, and JSON support. Browsers and most standard libraries only implement version 1.0. Version 3.1 requires a dedicated engine like Saxon.
How do I select nodes with a specific attribute value?
Use a predicate with the @ shorthand for the attribute axis. For example, //book[@category="fiction"] selects all book elements where the category attribute equals "fiction". You can combine multiple predicates: //book[@category="fiction"][@year > 2000].
Why does my XPath return no results even though the XML contains matching elements?
The most common cause is XML namespaces. If your XML declares a default namespace (xmlns="..."), elements belong to that namespace even without a prefix. In version 1.0, you must register the namespace and use a prefix in your expression. In browser JavaScript, pass a namespace resolver as the third argument to document.evaluate().
Can XPath modify XML content?
No. It is a read-only query language. It selects and evaluates nodes but cannot insert, delete, or update them. To modify XML, use XSLT transformations, DOM manipulation methods, or a library like Python's lxml that provides separate APIs for editing.
What does the double slash (//) mean in XPath?
The double slash is shorthand for the descendant-or-self axis. The expression //title means "select all title elements anywhere in the document tree, at any depth." It is equivalent to the full form /descendant-or-self::node()/title. Using // at the start of an expression searches the entire document; using it mid-path (like /catalog//title) searches descendants of a specific node.
How do I select text content instead of the element node?
Append /text() to your expression. For example, //book/title/text() returns the text content of each title element as a string node, rather than the element node itself. In code, you can also access .textContent on the returned element node without using text().
Is XPath faster than CSS selectors for querying XML?
CSS selectors are optimized for HTML and DOM traversal in browsers. XPath is more expressive: it supports parent traversal, sibling axes, numeric predicates, and built-in functions that CSS selectors cannot express. For HTML, CSS selectors (querySelector) are typically faster. For XML, most server-side libraries only expose XPath — CSS selectors aren't an option at all.