Selecting a CSS Class With Xpath

How can I find an element by CSS class with XPath?

This selector should work but will be more efficient if you replace it with your suited markup:

//*[contains(@class, 'Test')]

Or, since we know the sought element is a div:

//div[contains(@class, 'Test')]

But since this will also match cases like class="Testvalue" or class="newTest", @Tomalak's version provided in the comments is better:

//div[contains(concat(' ', @class, ' '), ' Test ')]

If you wished to be really certain that it will match correctly, you could also use the normalize-space function to clean up stray whitespace characters around the class name (as mentioned by @Terry):

//div[contains(concat(' ', normalize-space(@class), ' '), ' Test ')]

Note that in all these versions, the * should best be replaced by whatever element name you actually wish to match, unless you wish to search each and every element in the document for the given condition.

Selecting a css class with xpath

I want to write the canonical answer to this question because the answer above has a problem.

Our problem

The CSS selector:

.foo

will select any element that has the class foo.

How do you do this in XPath?

Although XPath is more powerful than CSS, XPath doesn't have a native equivalent of a CSS class selector. However, there is a solution.

The right way to do it

The equivalent selector in XPath is:

//*[contains(concat(" ", normalize-space(@class), " "), " foo ")]

The function normalize-space strips leading and trailing whitespace (and also replaces sequences of whitespace characters by a single space).

(In a more general sense) this is also the equivalent of the CSS selector:

*[class~="foo"]

which will match any element whose class attribute value is a list of whitespace-separated values, one of which is exactly equal to foo.

A couple of obvious, but wrong ways to do it

The XPath selector:

//*[@class="foo"]

doesn't work! because it won't match an element that has more than one class, for example

<div class="foo bar">

It also won't match if there is any extra whitespace around the class name:

<div class="  foo ">

The 'improved' XPath selector

//*[contains(@class, "foo")]

doesn't work either! because it wrongly matches elements with the class foobar, for example

<div class="foobar">

Credit goes to this fella, who was the earliest published solution to this problem that I found on the web:
http://dubinko.info/blog/2007/10/01/simple-parsing-of-space-seprated-attributes-in-xpathxslt/

Selenium C# Find Both Attribute And CSS Class, Using XPath or CssSelector

I prefer using CSS selectors because of the better support and speed over XPath. I've tested the below with the HTML you provided and it works.

private By PhoneError => By.CssSelector("input[ng-invalid][data-qa='homephone-update']");

How to select the las Li with Xpath or Css Selector

As the method name suggests, it can only return element, not text node. You can find the target <a> element first :

a = driver.find_element_by_xpath('//*[@class="pg"]/ul/li[last()]/a')

And then you can get the inner text from a.text

XPath how to find second element with CSS class name

Just access it by index (indexing starts with 1 in XPath):

(//*[contains(@class, 't-ticket-category-select-trigger')])[2]

Or, if it is the last one:

(//*[contains(@class, 't-ticket-category-select-trigger')])[last()]

CSS/Xpath selector for an element with a certain class containing an element with certain text

You can try to use below XPath expression:

.//div[div[text()="All versions "]]

This will match div that contains div with text "All versions "



Related Topics



Leave a reply



Submit