XPath Tester
Test XPath expressions against XML and see all matching nodes
XML Input
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.
XPath Tester Use Cases
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.
| Axis | Example | Description |
|---|---|---|
| child | child::book | Direct children named "book" |
| descendant | descendant::title | All "title" elements at any depth |
| parent | parent::* | The parent of the current node |
| ancestor | ancestor::catalog | All ancestors named "catalog" |
| following-sibling | following-sibling::book | Siblings after the current node |
| preceding-sibling | preceding-sibling::book | Siblings before the current node |
| attribute | attribute::lang | The "lang" attribute of the node |
| self | self::book | The current node if it is "book" |
| descendant-or-self | //title | Shorthand: any "title" in the tree |
| ancestor-or-self | ancestor-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.
| Function | Category | Description |
|---|---|---|
| text() | Node test | Selects text content of a node |
| position() | Numeric | Returns 1-based position in node set |
| last() | Numeric | Returns size of current node set |
| count() | Numeric | Counts nodes: count(//book) |
| contains() | String | contains(@class, "active") — substring match |
| starts-with() | String | starts-with(title, "The") — prefix match |
| normalize-space() | String | Strips leading/trailing whitespace |
| string-length() | Numeric | Returns character count of a string |
| sum() | Numeric | sum(//price) — totals numeric values |
| not() | Boolean | not(@disabled) — negation |
| name() | String | Returns 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.
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.98from 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) # → Trueimport 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# 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