— Developer Tools

Free XPath and CSS Selector Tester

Paste HTML or XML and a selector to see every element, attribute or value it matches, using your browser’s own engine.

— Samples
Valid
Live

What is a XPath and CSS Selector Tester?

CSS selectors and XPath are the two ways to point at elements in a web page or XML file. Test frameworks, scrapers and stylesheets all rely on them. This tester runs either one against markup you paste and lists every match.

It doesn’t reimplement either language. The markup goes through your browser’s DOMParser, CSS runs through querySelectorAll, and XPath through document.evaluate, the same engines Chrome DevTools uses for $$() and $x(). What matches here matches on a real page with the same markup.

Key Features

The Browser’s Own Engines

Selectors run on the same code your browser uses for pages and DevTools, including newer CSS such as :has() and :is() where your browser supports them.

Elements, Attributes and Text

XPath can return attribute and text nodes, not just elements, and the table labels which kind each match is. //a/@href lists link addresses directly.

Values From XPath Functions

Expressions such as count(//li), string(//h1) or boolean(//table) return their number, string or true or false instead of a node list.

HTML or XML Parsing

Markup starting with an XML declaration is parsed as strict, case-sensitive XML. Everything else is parsed as HTML and repaired the way browsers repair it.

Nothing Runs, Nothing Uploads

Pasted markup is parsed without running its scripts, and it never leaves the page.

Perfect for everyone

  • QA engineers writing Selenium
  • Playwright and Cypress locators
  • Developers building scrapers
  • Front-end developers debugging CSS rules
  • Anyone converting between CSS and XPath

How to Use the XPath and CSS Selector Tester

Paste markup, choose CSS or XPath, and type the selector.

1

Paste the Markup

Copy page source, a component’s HTML or an XML feed into the second box. Use the HTML your tool really receives, not what you see after scripts run.

2

Choose CSS or XPath

CSS suits styles and most test locators. Choose XPath when you need text matching, attributes as results or walking up the tree.

3

Type the Selector

Results update on every keystroke. The numbered list shows each match’s opening tag and text, in document order.

4

Check the Count

A test locator usually needs exactly one match. If you see more, add a class, attribute or position until only the right element is left.

Worked Examples

Selectors Run on Real Markup

Each example shows the selector, three dashes, then the HTML. The answer is what this tester returned in the chip’s mode, using the browser’s engines, so predict the matches first.

REF_001CSS class

“.lead --- <article id="post"><h1>Title</h1><p class="lead">Hello <a href="/docs">world</a></p><p>There</p><ul><li>One</li><li class="on">Two</li><li>Three</li></ul></article>”

REF_002CSS child and :not

“article > p:not(.lead) --- <article id="post"><h1>Title</h1><p class="lead">Hello <a href="/docs">world</a></p><p>There</p><ul><li>One</li><li class="on">Two</li><li>Three</li></ul></article>”

REF_003CSS nth-child

“li:nth-child(odd) --- <article id="post"><h1>Title</h1><p class="lead">Hello <a href="/docs">world</a></p><p>There</p><ul><li>One</li><li class="on">Two</li><li>Three</li></ul></article>”

REF_004CSS :has parent

“p:has(a) --- <article id="post"><h1>Title</h1><p class="lead">Hello <a href="/docs">world</a></p><p>There</p><ul><li>One</li><li class="on">Two</li><li>Three</li></ul></article>”

REF_005XPath position

“//li[2] --- <article id="post"><h1>Title</h1><p class="lead">Hello <a href="/docs">world</a></p><p>There</p><ul><li>One</li><li class="on">Two</li><li>Three</li></ul></article>”

REF_006XPath attribute

“//a/@href --- <article id="post"><h1>Title</h1><p class="lead">Hello <a href="/docs">world</a></p><p>There</p><ul><li>One</li><li class="on">Two</li><li>Three</li></ul></article>”

REF_007XPath count

“count(//li) --- <article id="post"><h1>Title</h1><p class="lead">Hello <a href="/docs">world</a></p><p>There</p><ul><li>One</li><li class="on">Two</li><li>Three</li></ul></article>”

REF_008XPath text match

“//li[contains(text(), "T")] --- <article id="post"><h1>Title</h1><p class="lead">Hello <a href="/docs">world</a></p><p>There</p><ul><li>One</li><li class="on">Two</li><li>Three</li></ul></article>”

REF_009Dangling combinator

“p > --- <p>One</p>”

REF_010Unclosed predicate

“//p[ --- <p>One</p>”

CSS to XPath

CSS Selectors and Their XPath Equivalents

Most selectors translate directly between the two languages, and a few only exist in one. These ten cover the everyday cases.

01 / ELEMENT

Element Name

Both select by tag name. XPath needs // to search at any depth, or a single / for a direct child.

“What is p in XPath?”

02 / CLASS

Class

CSS .lead matches any element whose class list includes lead. XPath has no class shortcut, so it pads the class attribute with spaces and searches inside it.

“What is .lead in XPath, matching exactly?”

03 / ID

ID

An ID selector becomes an attribute test in XPath. IDs should be unique, so both return at most one element on a valid page.

“What is #post in XPath?”

04 / CHILD

Child and Descendant

CSS article > p is a direct child and article p any descendant. XPath writes them //article/p and //article//p.

“What is article > p in XPath?”

05 / ATTRIBUTE

Attribute Tests

a[href] keeps links that have an href, and a[href^='/'] those starting with a slash. XPath uses predicates with @ and starts-with.

“What is a[href^='/'] in XPath?”

06 / POSITION

Position

li:nth-child(2) counts every sibling, while XPath’s //li[2] counts only li siblings. On a list holding only li elements, they agree.

“Which XPath picks the second li in each list?”

07 / TEXT

Text Content

CSS can’t select by text. XPath can, with text() for direct text or a dot for all text inside, including child elements.

“Can CSS select a button by its label?”

08 / GOING

Going Up the Tree

CSS :has() selects a parent by what it contains, as in p:has(a). XPath expresses the same with a predicate, or walks up with the parent and ancestor axes.

“What is p:has(a) in XPath?”

09 / SIBLINGS

Siblings

h2 + p is the paragraph directly after an h2, and h2 ~ p any later paragraph. XPath uses the following-sibling axis for both.

“What is h2 + p in XPath?”

10 / ATTRIBUTES

Attributes as Results

CSS always returns elements, while XPath can return attribute or text nodes. //a/@href lists the addresses themselves.

“Which language can return an attribute value?”

Where Selectors Are Used

The same two languages drive browsers, test frameworks, scrapers and XML tools.

Browser DevTools

In the Chrome or Firefox console, $$() runs CSS and $x() runs XPath on the same engines used here. The Elements panel’s search box accepts both.

Playwright and Cypress

Playwright locators accept CSS, XPath and text selectors, and Cypress uses CSS through cy.get. Test IDs and roles make steadier locators than long CSS paths.

Selenium WebDriver

By.cssSelector and By.xpath hand your selector to the browser’s engine. A selector that matches here matches there on the same markup.

Web Scraping Libraries

Python’s lxml and parsel, and Node’s cheerio, implement XPath or CSS themselves, so rare pseudo-classes may behave differently. Test against the HTML they download.

XSLT and XML Tools

XSLT, Schematron and XML databases use XPath, often versions 2.0 or 3.1 with many more functions. Browsers support XPath 1.0 only.

Stylesheets and Scripts

CSS rules and document.querySelectorAll in your own code share the selector syntax you test here.

Selector Mistakes

Most selectors that work in one place and fail in another fall into one of these.

Tip 01

Testing the Wrong HTML

Pages built by JavaScript differ from the HTML a scraper downloads. Paste the markup your tool really sees, from View Source or the HTTP response.

Tip 02

Brittle Absolute Paths

Copied XPath like /html/body/div[3]/div[2]/p breaks with any layout change. Anchor on an id, a data attribute or visible text instead.

Tip 03

Exact Class Comparison in XPath

//p[@class='lead'] fails on an element with class lead intro, because it compares the whole attribute. Use contains with the class padded by spaces.

Tip 04

Different Position Counting

li:nth-child(2) and //li[2] disagree when other element types share the parent. Check the table to see which elements you got.

Tip 05

Default Namespaces in XML

When the root element declares a default namespace, browsers match nothing for //book, since XPath 1.0 has no default namespace. Use //*[local-name()='book'].

Tip 06

XPath 2.0 Functions

matches(), lower-case() and string-join() belong to XPath 2.0 and fail in browsers. Use translate() for case-insensitive comparisons.

Tip 07

XPath Counts From One

//li[1] is the first item, unlike index 0 in JavaScript arrays. //li[0] matches nothing at all.

Tip 08

Whitespace Around Text

text()='Save' fails when the button has spaces or a line break around the word. Compare with normalize-space() instead.

XPath Axes CSS Can’t Match

Axes let XPath move in any direction from a node. These six do things no CSS selector can.

Tip 01

parent

//a[@href='/docs']/parent::p returns the paragraph holding a link, and the parent axis also has a short form of two dots after a slash.

Tip 02

ancestor

//button[text()='Save']/ancestor::form finds the form around a button, however deep the button sits. Add [1] for the closest one.

Tip 03

preceding-sibling

//li[@class='on']/preceding-sibling::li returns every item before the active one. CSS can only look forward to later siblings.

Tip 04

following

//h2[text()='Pricing']/following::table[1] finds the first table after a heading, even outside the heading’s parent. It’s handy on pages without useful classes.

Tip 05

self

self::p tests the current node’s type inside a predicate, as in //*[self::h2 or self::h3]. It selects several element names in one expression.

Tip 06

attribute and text

@ is short for attribute::, and text() selects text nodes. Together they pull values out of a page instead of elements.

When to Test a Selector

Before it goes into a test, a scraper or a stylesheet, and whenever one stops matching.

Writing a Test Locator

Check that a Playwright, Cypress or Selenium selector matches exactly one element before the test runs.

Fixing a Broken Scraper

Paste the current page source and see whether your selector still matches after a site redesign.

Converting Between CSS and XPath

Run both versions on the same markup and confirm they select the same nodes.

Extracting Links and Attributes

Use //a/@href or //img/@src to list every address on a page in one go.

Debugging a Stylesheet Rule

Find out why a CSS rule doesn’t apply by checking which elements its selector actually matches.

Querying an XML Feed

Paste an RSS feed or a sitemap and pull out titles, links or dates with XPath.

Answering Quick Questions

count() and boolean() tell you how many products a page lists, or whether a table is present, in one expression.

Frequently Asked Questions