Troy Wray
Troy Wray

Reputation: 1018

XPath V1.0 contains() not specific enough

I have an application that requires me to find a XPath selector for an element and then see if that XPath can be simplified.

So if I have

<a class="abc def gh">

I may determine that the XPath

a[contains(@class, "abc") 

is specific enough. The problem is, it also selects items with class "abcxyz",

Is there a way to select items with ONLY class "abc"?

i.e. I think it's clear but I want to find items that have a class of "abc" or "abc def" but not "abcxyz".

Here's a more specific example because I believe neither of the answers so far works:

<div>
    <span id="x" class="btnSalePriceLabel">Sale:</span> 
    <span id="y" class="btnSalePrice highlight">$20.40</span>
</div>

I want whatever XPath selector will select the 2nd span and not the first.

If I try

//span[@class and contains(concat(' ', normalize-space(@class), ' '), ' btnSalesPrice ')]

I get nothing selected. Likewise with

//span[contains(concat(' ', normalize-space(@class), ' '), ' btnSalesPrice ')]

Upvotes: 0

Views: 54

Answers (2)

eLRuLL
eLRuLL

Reputation: 18799

it is better if you use css for this exact matches, specially with class attributes, in which case it would be:

a.abc

You can use different css-to-xpath converters on several languages (check this one for example on javascript) and its transformation would be:

descendant-or-self::a[@class and contains(concat(' ', normalize-space(@class), ' '), ' abc ')]

Upvotes: 1

alecxe
alecxe

Reputation: 473863

Since class attribute is a multi-valued attribute, you have to account for these spaces between the values with concat():

//a[contains(concat(' ', normalize-space(@class), ' '), ' abc ')]

Note that CSS selectors have this ability to match specific class values built-in:

a.abc

I think you can see what is more concise and readable.

Upvotes: 1

Related Questions