DevToolsmith

XPath Tester

Test XPath expressions against XML and see every matching element, attribute or text node with its path, or the number, string or boolean result of functions like count() and sum(). Uses your browser’s XPath 1.0 engine, and namespace prefixes work automatically.

Runs 100% in your browser — nothing is uploaded

XML
Tip: drop a file here770 chars · 770 bytes · 22 lines
Result

Loading…

Examples for the sample XML

ExpressionSelects
//book/dc:title/text() Text of every title (namespace prefixes from the document just work)
//book[price > 20]/@id id attribute of books over 20
//book[@category='programming'][last()] The last programming book
//book[contains(author, 'Kim')] Books whose author contains “Kim”
//price[@currency='USD']/.. Parent of every USD price (the book)
count(//book) Number of books
count(//book[@category='programming']) Number of programming books
//book[not(@lang)]/@id Books without a lang attribute
//comment() Comments

XPath syntax cheat sheet

ExpressionMeaning
/catalog/book book children of the root catalog element (absolute path)
//book book elements anywhere in the document
book/@id the id attribute of book children of the current node
.. the parent of the current node
//book[1] every book that is the first book child of its parent
(//book)[1] the first book in the whole document
//book[price > 20 and @lang] books with a price over 20 and a lang attribute
//*[local-name()="title"] title elements in any namespace
//author/following-sibling::price price elements that come after an author with the same parent

XPath in code

Python (lxml)
from lxml import etree

doc = etree.parse("catalog.xml")
doc.xpath("//book[price > 20]/@id")              # ['bk101', 'bk103']
doc.xpath("//dc:title/text()", namespaces={"dc": "http://purl.org/dc/elements/1.1/"})
JavaScript (browser)
const doc = new DOMParser().parseFromString(xml, 'application/xml');
const result = doc.evaluate('//book[price > 20]/@id', doc, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
for (let i = 0; i < result.snapshotLength; i++) console.log(result.snapshotItem(i).value);

// In DevTools, on the current HTML page:
$x('//a/@href')
Shell (xmllint)
xmllint --xpath '//book[price > 20]/@id' catalog.xml

Querying JSON instead? Use the JSONPath tester or the jq playground. To tidy the XML first, use the XML formatter.

Frequently asked questions

Which XPath version is supported?

XPath 1.0, evaluated by your browser’s own engine, the same one behind document.evaluate() and $x() in DevTools, and the version used by XSLT 1.0, Selenium, Scrapy, lxml and most libraries. XPath 2.0 and 3.1 functions such as matches(), lower-case() or string-join() are not available.

How do I query XML with namespaces?

Use the prefixes declared in the document: if it declares xmlns:dc="…", //dc:title works here, because every prefix declared anywhere in the document is registered automatically. Elements in a default namespace (xmlns="…" without a prefix) can’t be matched by a bare name in XPath 1.0; use //*[local-name()="book"] instead.

Why does //book[1] return more than one node?

Because [1] applies to each step, not to the whole result: //book[1] means “every book that is the first book child of its parent”. If books sit under different parents, you get one per parent. Wrap the path in parentheses to number the overall result: (//book)[1].

Can I use it for HTML?

Only if the HTML is well-formed XML (XHTML), because the input is parsed as XML: tags must be closed, attributes quoted, and entities like &nbsp; aren’t defined. For real web pages, run $x("//a/@href") in the browser’s DevTools console, which evaluates XPath against the live HTML document.