XPath Tester

Test and evaluate XPath expressions against HTML or XML online. Free XPath tester with live results, match highlighting, and support for XPath 1.0 axes, predicates, and functions.

An XPath expression that works in one document structure will silently return zero nodes in another. And when you are building a scraper, writing a test, or extracting data from an XML feed, silent failure is the most expensive kind. You write the expression, run the pipeline, get empty results, and have no idea whether the problem is the path, the namespace, the document shape, or a subtle difference in how the parser handles whitespace.

This XPath tester lets you paste HTML or XML, write an expression, and see exactly which nodes match before you commit the expression to your code. It runs entirely in your browser using the native DOMParser and document.evaluate() APIs. No data leaves your machine, no backend is involved, and the results are instant.

How to test XPath expressions online

The tool has a straightforward two-step workflow that matches how most developers think about XPath.

  1. Paste your document into the HTML/XML input area. Use the toggle to switch between HTML and XML parsing modes. HTML mode is forgiving (the browser's built-in parser auto-corrects malformed markup). XML mode is strict and will flag parse errors.
  2. Enter an XPath expression in the expression field and click Evaluate (or press Enter). The tool evaluates the expression against the parsed document and displays every matching node with its type, tag name, text content, and serialized HTML.

Quick-fill preset buttons below the expression field cover common patterns: selecting all links, all images, headings, elements with a specific class, and meta tags. Click a preset to populate the expression, then modify it to match your use case.

For each matched node, you can expand the row to see the full serialized output, the actual HTML or XML that the expression selected. This is useful for debugging: it tells you not just how many nodes matched, but exactly what they contain.

The XPath evaluator also handles non-node results. Expressions that return strings (like string(//title)), numbers (count(//div)), or booleans (boolean(//meta[@name='robots'])) display the scalar result directly instead of a node list.

What is XPath and why developers use it

XPath (XML Path Language) is a query language for selecting nodes from an XML or HTML document. It uses a path-based syntax that navigates the document tree, similar to how file system paths navigate directories. Unlike CSS selectors, XPath can traverse the tree in any direction: up to parents, sideways to siblings, and down to descendants. That makes it strictly more powerful for complex selection tasks.

Developers use XPath in three main contexts:

  • Web scraping and data extraction. Libraries like Python's lxml, scrapy, and JavaScript's document.evaluate() accept XPath expressions to locate and extract content from web pages.
  • Browser automation testing. Selenium, Playwright, and Puppeteer support XPath selectors for locating elements when CSS selectors cannot express the required condition (e.g., selecting by text content or navigating upward).
  • XML processing. XSLT transformations, XML Schema validation, and XML database queries all rely on XPath to address specific nodes within structured documents.

The version used by modern browsers and most libraries is XPath 1.0, which is the version this XPath tester evaluates. XPath 2.0 and 3.0 exist but are not natively supported by browser engines.

XPath syntax reference

XPath syntax combines path expressions, axes, predicates, and functions. Here is a reference covering the most useful constructs you will encounter.

Path expressions

Expression Selects
/html/body/div Direct child <div> of <body> (absolute path)
//div All <div> elements anywhere in the document
//div/p All <p> that are direct children of a <div>
//div//p All <p> that are descendants of a <div> (any depth)
//* All elements in the document
//div/@class The class attribute of every <div>
//text() All text nodes in the document

Axes

Axes define the direction of traversal relative to the current node. They are what make XPath more expressive than CSS selectors.

Axis Direction Example
child:: Direct children child::div (same as ./div)
parent:: Immediate parent parent::div (or ..)
ancestor:: All ancestors up to root ancestor::form
descendant:: All descendants at any depth descendant::span
following-sibling:: Siblings after the current node following-sibling::li
preceding-sibling:: Siblings before the current node preceding-sibling::li
self:: The current node itself self::div
attribute:: Attributes of the node attribute::href (or @href)

Predicates

Predicates filter the node set by adding conditions inside square brackets.

Expression Selects
//a[@href] Links that have an href attribute
//div[@class='main'] Divs where class is exactly "main"
//li[position()=1] First <li> child of each parent (same as //li[1])
//li[last()] Last <li> child of each parent
//p[contains(text(), 'error')] Paragraphs containing the text "error"
//input[@type='text' and @name] Text inputs that also have a name attribute
//div[not(@class)] Divs without a class attribute

Functions

XPath 1.0 includes string, numeric, and boolean functions that operate on node values and attributes.

Function Returns Example
contains(str, sub) Boolean //div[contains(@class, 'nav')]
starts-with(str, prefix) Boolean //a[starts-with(@href, '/api')]
normalize-space(str) String //p[normalize-space()='Hello']
string-length(str) Number //p[string-length() > 100]
count(nodeset) Number count(//li)
text() Text nodes //h1[text()='Welcome']
not(expr) Boolean //img[not(@alt)]
concat(str1, str2, ...) String concat(//title, ' - ', //meta[@name='author']/@content)

Common XPath expressions for web scraping

If you are writing a scraper, these are the expressions you will reach for repeatedly. Test each one in this XPath tester against your target page's HTML before adding it to your scraping code.

Task XPath Expression
Get page title string(//title)
All external links //a[starts-with(@href, 'http')]
Images without alt text //img[not(@alt) or @alt='']
Meta description //meta[@name='description']/@content
All headings (h1-h6) //h1 | //h2 | //h3 | //h4 | //h5 | //h6
Table rows //table//tr[position() > 1]
Form inputs //form//input[@type!='hidden']
Element by data attribute //*[@data-testid='submit-button']
Nth item in a list //ul[@class='results']/li[3]
Sibling after a label //label[text()='Email']/following-sibling::input

Each of these expressions can be tested directly in this tool. Paste the target page's HTML, run the expression, and verify it selects the correct nodes before committing it to your Python, JavaScript, or Ruby scraping code.

XPath vs CSS selectors: when to use which

Both XPath and CSS selectors address nodes in a document tree. CSS selectors are more familiar to frontend developers and slightly faster in browser engines. XPath is more powerful and handles cases CSS cannot express.

Capability CSS Selectors XPath
Select by tag, class, id Yes Yes
Select by attribute value Yes Yes
Navigate to parent/ancestor No Yes
Select by text content No Yes
Select preceding siblings No Yes
Boolean conditions (and/or/not) Limited Yes
Return attribute values directly No Yes
Count, string, math functions No Yes
XML namespace support No Yes
Browser performance Faster Slightly slower

Use CSS selectors when you are selecting elements by tag, class, id, or attribute and do not need to navigate upward or sideways. They are the default choice for Playwright, Puppeteer, and DOM manipulation in JavaScript.

Use XPath when you need to select by text content (//a[contains(text(), 'Next')]), navigate to ancestors (ancestor::form), select preceding siblings, or return attribute values directly. XPath is also the only option for processing pure XML documents and when working with Selenium locators or Python's lxml library.

Debugging XPath expressions: common mistakes

When an XPath expression returns zero matches or the wrong nodes, the problem is usually one of these issues. Use this XPath tester to experiment with corrections until the expression matches what you expect.

  1. Single slash vs double slash. /div/p selects <p> children directly under root <div>. //div//p selects any <p> that is a descendant of any <div> at any depth. Most of the time you want //.
  2. Case sensitivity. XPath is case-sensitive. //DIV will not match <div> in HTML mode (where the browser lowercases tag names). In XML mode, tag case must match exactly.
  3. Text matching with whitespace. //p[text()='Hello'] requires an exact match including whitespace. Use normalize-space() to trim: //p[normalize-space()='Hello']. Or use contains() for partial matches.
  4. Class attribute matching. //div[@class='nav'] only matches if the class attribute is exactly "nav". For elements with multiple classes like class="nav main sidebar", use contains(@class, 'nav'). Be aware this will also match "navigation", so add spaces if needed: contains(concat(' ', @class, ' '), ' nav ').
  5. Missing namespace handling. XML documents with namespaces require a namespace resolver. In this browser-based tester, the default resolver handles the most common cases, but heavily namespaced XML may need explicit namespace prefixes in your production code.
  6. Position index starting at 1. XPath positions are 1-based, not 0-based. //li[1] selects the first item. //li[0] selects nothing.
  7. HTML auto-correction. The browser's HTML parser auto-corrects malformed markup (adds missing closing tags, moves elements). The parsed DOM may differ from the raw source. Switch to XML mode for strict parsing, or inspect the serialized output in the results to see what the parser actually produced.

Frequently Asked Questions

How do I test an XPath expression without writing code?

Paste your HTML or XML into this XPath tester, enter the expression, and click Evaluate. The tool shows every matching node instantly, without any code or setup. It runs entirely in your browser.

Is my data sent to a server when I use this XPath evaluator?

No. All parsing and evaluation happens locally in your browser using the native DOMParser and document.evaluate() APIs. No data leaves your machine at any point.

What is the difference between XPath and CSS selectors?

Both select elements in a document tree, but XPath can navigate upward (to parents and ancestors), select by text content, use boolean logic, and return non-element values like attributes and counts. CSS selectors are faster in browsers and sufficient for most forward/downward selection. Use XPath when CSS cannot express the query.

Why does my XPath return no matches even though the element exists?

Common causes: case sensitivity (XPath is case-sensitive), exact vs partial attribute matching (@class='nav' vs contains(@class, 'nav')), whitespace in text content (use normalize-space()), and position indexing starting at 1 instead of 0. Try this tool to test variations of your expression until you find the correct one.

Does this tool support XPath 2.0 or 3.0?

This tool uses the browser's native document.evaluate() which implements XPath 1.0. XPath 2.0 and 3.0 add features like regular expressions, date functions, and quantified expressions, but they are not supported by browser engines. For XPath 2.0/3.0 evaluation, you need server-side tools like Saxon.

What is the difference between HTML and XML mode?

HTML mode uses the browser's forgiving HTML parser, which auto-corrects malformed markup (adding missing tags, fixing nesting). XML mode uses a strict XML parser that requires well-formed input and reports parse errors. Use HTML mode for web page content and XML mode for API responses, feeds, and structured data files.

Can I use this tool to build XPath expressions for Selenium?

Yes. Paste the page's HTML source into this tester, write your expression, and verify it matches the correct elements. Once the expression works here, use it directly in Selenium with driver.find_element(By.XPATH, "your_expression"). The browser's XPath engine is the same one Selenium uses.

How do I select elements by text content with XPath?

Use the text() function or contains(). For exact match: //a[text()='Click here']. For partial match: //a[contains(text(), 'Click')]. For case-insensitive match, use translate(): //a[contains(translate(text(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), 'click')].

Related Free Tools

Give your AI agent a faster, leaner browser

Structured page data instead of raw HTML. Your agent processes less, decides faster, and costs less to run.

Stability detection built in
Fraction of the payload size
Diffs after every action
No credit card required. 1 hour of free runtime included.