XPath Tester

Test XPath 1.0 expressions against an XML or HTML document and see every matching node, its path and its value.

Parse as:

Paste a document above, type an XPath expression, and the matching nodes appear instantly.

XPath 1.0 syntax cheat sheet
/library/book
Absolute path โ€” book children of the root library.
//title
Every title element anywhere in the document.
//book/@id
The id attribute node of every book.
//book[2], //book[last()]
Positional predicates โ€” XPath counts from 1, not 0.
//book[@price < 10]
Predicate comparing an attribute as a number.
//book[title='Sword of Honour']
Predicate on a child element's string value.
//book[contains(title, 'Lord')]
String functions: contains, starts-with, substring, normalize-space.
count(//book), string(//title)
Expressions may return a number, string or boolean instead of a node-set.
//title/text(), //comment()
Node tests for text, comment and processing-instruction nodes.
//book/following-sibling::book
Axes: child, parent, ancestor, descendant, following-sibling, preceding-sibling, self.
//a | //b
Union of two node-sets.
//d:title
XPath 1.0 has no default namespace, so a document whose root declares xmlns="โ€ฆ" is bound here to the prefix d. Prefixes declared in the document (xmlns:x="โ€ฆ") keep their own names.
No uploads. Your files stay on your device.

Free forever, no sign-up, no cookies. Buy me a coffee

How it works

Paste an XML or HTML document, type an XPath expression, and every match is evaluated as you type. The document is parsed with the browser's own DOMParser and the expression is run through document.evaluate(), the DOM Level 3 XPath API, which implements XPath 1.0 (W3C Recommendation, 16 November 1999). What you see here is therefore exactly what your own browser-side code, Selenium or Playwright would select โ€” the same engine and the same rules, including 1-based positions, the XPath string-value of an element, and the node-set, number, string and boolean result types.

Each match is listed with its node kind, a rebuilt absolute path such as /library/book[2]/@id, the node's markup and its text value. Namespaces are resolved from the declarations in your document: xmlns:x="โ€ฆ" keeps the prefix x, and because XPath 1.0 has no concept of a default namespace, a root xmlns="โ€ฆ" is bound to the prefix d so you can write //d:title. XML that is not well formed reports the parser's own message; switch to HTML mode for markup with unclosed tags, which the HTML parser repairs the way a browser does. Everything runs in your browser โ€” no upload, no account, no ads โ€” so it is safe to test selectors against private feeds, sitemaps, SOAP payloads and scraped pages.

Frequently asked questions

Which version of XPath does this tester support?

XPath 1.0, the W3C Recommendation of 16 November 1999. Expressions are evaluated by your browser's own DOM Level 3 XPath engine through document.evaluate(), which is the same engine Selenium, Playwright and browser devtools use, so a path that works here works in your automation code. XPath 2.0 and 3.1 functions such as matches() or tokenize() are not available in any browser and will report a syntax error.

Why does my expression match nothing when the document has an xmlns attribute?

XPath 1.0 has no default namespace, so an unprefixed name like //title only matches elements with no namespace at all. If your root element declares xmlns="http://www.w3.org/2005/Atom", write //d:title instead: this tool binds the document's default namespace to the prefix d. Prefixes you declare yourself with xmlns:x="..." keep their own names and can be used directly.

Can I test XPath against HTML as well as XML?

Yes. Switch the Parse as option to HTML and the markup is parsed with the browser's HTML parser, which repairs unclosed tags and implied elements exactly as a real page load would, so //li or //div[@class='price'] behave the way they will in your scraper. XML mode is strict instead and reports the parser's own message with the line and column when the document is not well formed.

Report a bug