XPath Tester
Paste an XML or HTML document, type an XPath expression and instantly see which nodes match, highlighted in the document and listed with their full paths and values. Numbers, strings and booleans from functions like count() are shown too. Everything runs locally with your browser's XPath engine.
Last updated:
Results
Runs the browser's built-in XPath 1.0 engine on your own device; nothing is uploaded. Tip: click a result to jump to it in the document.
How to use the XPath Tester
- Paste your document into the Document box or open a file, and choose Parse as XML or Parse as HTML. A sample is loaded to start with.
- Type an XPath expression in the box at the top, or click an example chip to try one.
- Read the summary: how many nodes matched, or the number, string or boolean result of a function.
- Check the highlights in the formatted document on the right and the result list below; click a result to jump to it.
- Copy the values, markup or XPath paths of all matches for use in your code or scraper.
XPath cheat sheet
| Expression | Selects |
|---|---|
/library/book | book children of the root element library |
//book | all book elements anywhere in the document |
//book/@id | the id attribute of every book |
//book[1] | each book that is the first book child of its parent |
(//book)[1] | the first book in the whole document |
//book[last()] | the last book of each parent |
//book[@lang='fr'] | books whose lang attribute equals fr |
//book[price > 30] | books with a price child greater than 30 |
//book[not(@available)] | books without an available attribute |
//title/text() | the text nodes inside title elements |
//*[not(*)] | leaf elements (no child elements) |
//book | //magazine | union of both node sets |
Axes
| Axis | Short form | Meaning |
|---|---|---|
child:: | title | direct children (the default axis) |
descendant-or-self::node()/ | // | the node and everything below it |
attribute:: | @ | attributes |
parent::node() | .. | the parent |
self::node() | . | the current node |
ancestor:: | - | parent, grandparent and up to the root |
following-sibling:: / preceding-sibling:: | - | siblings after / before the node |
following:: / preceding:: | - | all nodes after / before it in document order |
XPath 1.0 functions
| Group | Functions |
|---|---|
| Node sets | last(), position(), count(), name(), local-name(), namespace-uri(), id() |
| Strings | string(), concat(), contains(), starts-with(), substring(), substring-before(), substring-after(), string-length(), normalize-space(), translate() |
| Numbers | number(), sum(), floor(), ceiling(), round() |
| Booleans | boolean(), not(), true(), false(), lang() |
Case-insensitive match in XPath 1.0: //title[contains(translate(., 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), 'xpath')]. Match a CSS class among several: //li[contains(concat(' ', normalize-space(@class), ' '), ' sale ')].
Frequently asked questions
What is XPath?
XPath (XML Path Language) is a W3C query language for selecting parts of an XML or HTML document. An expression like //book[price > 30]/title walks the document tree and returns matching nodes, or computes a value with functions such as count() and sum(). It is used in XSLT, Selenium and Playwright locators, web scrapers, and XML libraries in nearly every programming language.
Which XPath version does this tester use?
It uses the XPath 1.0 engine built into your browser (document.evaluate), the same version supported by browsers, Selenium, lxml, libxml2, Python's ElementTree subset and Java's default javax.xml.xpath. XPath 2.0 and 3.1 functions such as lower-case(), ends-with(), matches() or max() are not available; use translate(), contains(), starts-with() and substring() instead.
Why does my XPath return nothing on XML with xmlns?
When the root element declares a default namespace (xmlns="…"), every unprefixed element belongs to that namespace and a plain //item does not match it in XPath 1.0. This tool ignores the default namespace by default so plain names work. Untick that option to use the prefix d: instead, for example //d:item. Prefixes declared in the document, like atom: or soap:, are resolved automatically.
What is the difference between / and // in XPath?
A single slash selects direct children: /library/book returns book elements that are children of the root library element. A double slash selects descendants at any depth: //book returns every book element anywhere in the document, and //book//title every title inside a book, however deeply nested.
How do I select an element by attribute or text?
Use a predicate in square brackets. //book[@id='b2'] selects by attribute value, //book[title='Mastering XPath'] by child text, //a[contains(@href, 'example')] by part of an attribute, and //p[contains(., 'Contact')] by text anywhere inside the element. Use normalize-space() to ignore extra whitespace.
Is HTML handled differently from XML?
Yes. In HTML mode the page is parsed like a browser would, so unclosed tags are fixed and missing html, head, body and tbody elements are added automatically. Remember the added tbody when you copy an XPath from table markup: //table//tr is safer than //table/tr. Tag names are matched in lowercase.
Is my document uploaded?
No. Parsing and XPath evaluation happen in JavaScript inside this page, so your XML or HTML never leaves your device.
Are all the tools on FreeToolCabin tested for quality and accuracy?
Yes! Every tool on our site undergoes automated Q/A testing in real browser environments to ensure high precision, correct output, and zero errors. If you happen to spot a bug or have a suggestion, please contact us at [email protected] and our team will review it right away.