XML XPath Tester

Test XPath 1.0 expressions against XML or HTML documents online using our XPath validator & playground. Uses native browser document.evaluate(). 100% client-side.

100% private · runs locally

Evaluate XPath expressions against any XML or HTML document in real time. Perfect for debugging Selenium web scrapers, Scrapy spiders, and automated tests. Uses the browser's native document.evaluate() XPath 1.0 engine — no external libraries required. Results show the full serialized node content and node type (element, text, attribute) for each match. If you need to fix your XML formatting first, use our XML Formatter or check for errors with our XML Validator.

XPath
XML input
Matches No matches
Results will appear here

XPath Cheat Sheet

Expression Description
Basic Selection
/Selects from the root node
//Selects nodes anywhere in the document
.Selects the current node
..Selects the parent of the current node
@attrSelects attributes named "attr"
*Matches any element node
node()Matches any node type (element, text, comment)
text()Matches text nodes
Predicates & Filters
//book[1]Selects the first book element (1-based index)
//book[last()]Selects the last book element
//book[position()<3]Selects the first two book elements
//div[@id='x']Selects div elements with id exactly 'x'
//div[@class]Selects div elements that have a class attribute (any value)
//book[title and author]Selects books that have both a title and an author element
//book[@category='web' or @category='seo']Selects books where category is 'web' OR 'seo'
Axes (Advanced Navigation)
parent::node()Selects the parent of the current node (same as ..)
child::divSelects all direct div children (same as default behavior)
ancestor::divSelects all div ancestors (parent, grandparent, etc.) up to the root
descendant::spanSelects all span descendants (children, grandchildren, etc.)
following-sibling::*Selects all siblings after the current node
preceding-sibling::*Selects all siblings before the current node
Common Functions
//*[contains(@class, 'btn')]Selects elements whose class attribute contains the substring 'btn'
//*[starts-with(@id, 'user-')]Selects elements whose id attribute starts with 'user-'
//div[normalize-space(text())='Log in']Selects divs with exact text 'Log in', ignoring leading/trailing whitespace
count(//book)Returns the number of book elements as a number
//*[not(contains(@class, 'hidden'))]Selects elements that do NOT have 'hidden' in their class attribute
string-length(//title[1])Returns the string length of the first title element
//*[translate(@name, 'ABC', 'abc')='test']Case-insensitive match in XPath 1.0 using the translate function
Operators
//h1 | //h2Union operator: Selects all h1 and h2 elements
//book[price > 30]Selects books where price element is strictly greater than 30
//book[price <= 30]Selects books where price element is less than or equal to 30
//book[price != 30]Selects books where price element is not exactly 30

Using XPath in Selenium, Scrapy, and Playwright

Selenium WebDriver

Selenium relies heavily on XPath for robust web scraping and testing. Avoid absolute paths (like /html/body/div[2]/ul/li[3]) as they break when the layout changes. Use relative paths based on unique attributes.

from selenium.webdriver.common.by import By

# Finds the first button containing the text 'Submit'
element = driver.find_element(By.XPATH, "//button[contains(text(), 'Submit')]")

Scrapy

Scrapy spiders use XPath natively to extract structured data from HTML responses. You can extract element properties, text nodes, or specific attributes directly.

# Extracts the 'href' attribute from all links inside a specific div
links = response.xpath("//div[@id='navigation']//a/@href").getall()

# Extracts the text content of the product title
title = response.xpath("//h1[@class='product-title']/text()").get()

Playwright

Playwright supports multiple selector engines but specifically allows XPath selection. Playwright automatically waits for the element to be visible.

# Using the locator API with an xpath= prefix
submit_button = page.locator("xpath=//button[@type='submit']")
await submit_button.click()

Common XPath Errors

Invalid Expression vs Valid-But-Empty: If your expression has a syntax error (like unmatched brackets), the XPath evaluator will throw an exception. If the syntax is valid but no elements match, it simply returns an empty result (0 matches). Always double-check your spelling and case sensitivity.

Forgetting the Double Slash (//): Writing div[@class='test'] means "find a div at the current exact node level". You almost always want //div[@class='test'] to search anywhere in the document.

Dot (.) vs Slash (/) at the Beginning: In tools like Scrapy, if you have a selected node and want to search inside it, you must use .//a. Using //a will search the entire document again, ignoring your current node context.

XML Namespaces: The number one pitfall in strict XML is namespaces. If your XML has xmlns="http://example.com", standard queries like //book will fail because XPath expects the prefix. You must use //*[local-name()='book'].

Contains vs Exact Match: @class='btn' expects the class to be exactly "btn" and nothing else. If the element is <div class="btn primary">, it will fail. Use contains(@class, 'btn') for multiple classes.

Related tools

Frequently asked questions

What is XPath?

XPath (XML Path Language) is a query language for selecting nodes from an XML document. It uses path expressions to navigate the document tree, similar to how file paths navigate a directory. XPath is used in XSLT transformations, XML Schema, XQuery, Selenium test selectors, and many server-side XML processing libraries.

Is this an XPath validator or a tester?

It is both. It acts as an XPath validator by verifying the syntax of your expression (showing errors if the XPath is invalid) and as an XPath tester by executing valid expressions against your XML/HTML input to show exactly which nodes are selected.

Which XPath version is supported?

This tool supports XPath 1.0, as it uses the native browser document.evaluate() API. Features from XPath 2.0 and 3.0 (like sequences, strong typing, or regex functions such as matches()) are not available in standard browser engines.

Can I test XPath against HTML?

Yes, you can test XPath against HTML, provided the HTML is well-formed (like XHTML). Because the engine parses the input strictly as XML, unclosed tags or missing quotes on attributes will result in a parsing error.

Why does my XPath work in Chrome DevTools but not here or in Selenium?

Chrome DevTools evaluates XPath against the live DOM, which is parsed by an HTML parser that auto-corrects malformed tags and implicitly handles <tbody> elements in tables. This tester (and tools like Scrapy or Selenium) often evaluate against raw XML or strict HTML source code, requiring exact paths and valid markup.

How does XPath handle namespaces?

XPath 1.0 requires namespace prefixes to be registered with a namespace resolver. This tester uses null for the resolver, which works seamlessly on documents without namespace prefixes. For namespace-prefixed XML, use local-name-based expressions like //*[local-name()='elementName'].