XPath Tester
Evaluate an XPath expression against XML or HTML input and see every matching node, attribute or text value next to its resolved path. Runs entirely in your browser.
Input
Output
| Path | Value |
|---|---|
| No data yet | |
Guides
The XPath Tester runs an XPath expression against an XML (or HTML) document and instantly shows every matching element, attribute or text value alongside its resolved path (for example /store/book[2]/title). It's a fast way to build, debug and verify the XPath expressions used in scrapers, XSLT stylesheets, test automation locators and data pipelines — no install, no sign-up.
How to use it
- Paste or type your XML or HTML into the XML (or HTML) input box. You can load a sample bookstore catalog with Try an example.
- Enter an XPath expression such as
/store/book[@category='fiction']/title. - The results update as you type: a summary of how many nodes matched, plus a Path / Value table listing each match with its concrete resolved path. Copy the table or download it as CSV.
Because each match is shown with its fully-resolved path, you can see not just what matched but where it lives in the document — invaluable when // or * returns more than you expected.
Supported XPath syntax
This tester implements a practical subset of XPath 1.0:
/a/b/c— an absolute path from the document root (expressions must start with/).//book— descendant-or-self: matches abookelement anywhere in the document. Works mid-path too, e.g./store//title.*— wildcard: any element name, e.g./store/*.@attr— attribute selection, e.g.//book/@category.@*selects every attribute on the matched element(s).text()— the matched element's direct text-node children (one row per text node).- Predicates in
[ … ], one or more per step:[n]— 1-indexed position among that step's matches for a given parent.[last()]— the last match for a given parent.[@attr]— the attribute exists.[@attr='value']— the attribute equals a quoted literal.[child]— a child element with that name exists.[child='value']— a child element's text content equals a quoted literal.and/orcombinations of the above, with()grouping — e.g.[@category='fiction' and price='8.99'].
count(EXPR)— wraps a whole path expression and returns the match count instead of the matches themselves.
Not supported — and these throw a clear error rather than silently matching nothing (or, worse, matching too much): the | union operator, any axis other than child/descendant-or-self (parent::, following-sibling::, ancestor::, …), comparison operators other than = inside a predicate (>, <, !=, …), unquoted/numeric predicate values, functions other than text(), last() and count() (contains(), starts-with(), position() as a standalone comparison, …), and relative paths that don't start with /. Namespace prefixes in a tag name (ns:tag) are matched literally against the raw name, without namespace-prefix resolution.
The input parser also tolerates common HTML shortcuts — void elements (<br>, <img>, <input>, …) don't need a closing tag or self-closing slash, and unquoted attribute values (type=text) are accepted — so you can test XPath against real HTML fragments, not just strict XML.
What does XPath do?
XPath is a query language for selecting nodes in an XML (or HTML) document, the same way JSONPath queries JSON. Instead of writing loops to walk a tree of elements, you describe the location you want — an absolute path, a wildcard, a predicate — and let the evaluator find every match.
Why show the resolved path for each match?
An expression like //title can match values scattered across many different parents. Listing the resolved path (/store/book[2]/title) for each hit removes the ambiguity and makes it obvious which value came from where, so you can tighten your expression with confidence.
What happens if my XML/HTML or expression is invalid?
Malformed markup (an unclosed or mismatched tag) is flagged on the input field before evaluation runs. If the expression uses unsupported syntax, or is malformed, or simply matches nothing, you get a clear message — the tool never silently reports "no matches" for a query it couldn't actually evaluate.
Is my data private?
Yes. This tool runs entirely in your browser. Your XML/HTML and your expressions are never uploaded to a server — the parsing and evaluation happen locally on your device, which also means it keeps working offline.
What if I need to query JSON instead?
Use the JSONPath Tester — the same idea, applied to JSON documents with JSONPath expressions. If your XML needs formatting first, the XML Formatter will pretty-print or validate it before you write your XPath.