16

I would like to locate this element,

<div class="item-price">$0.99</div>

using XPath which says select div elements whose class attribute equals "item-price" and whose content contains a dollar sign ($).

kjhughes
  • 98,039
  • 18
  • 159
  • 218
Terrence Brannon
  • 4,388
  • 6
  • 36
  • 61
  • 1
    An attribute is matched with `@attributename`, you can use the `contains()` function on the content. Could you give us your best effort using those 2? – Wrikken Oct 21 '13 at 20:15
  • OK. `//div[@class="item-price" and contains("$")]` but I'm unsure of how to make conjunctions. I've also seen `//div[one][theother]`. – Terrence Brannon Oct 21 '13 at 20:28
  • 1
    Have you looked at the [documentation of `contains()`](http://www.w3.org/TR/xpath/#function-contains)? You're very close (`contains(.,'$')` would do it) – Wrikken Oct 21 '13 at 20:35

3 Answers3

26

This XPath expression:

//div[contains(@class, 'item-price') and contains(., '$')]

Will match all div elements of the item-price class containing a '$'.

It's useful to use contains() in the test on @class if you want to match cases where there are multiple CSS styles specified in the @class value.


Caution: For a more robust solution, apply the following technique to avoid unintended substring matches (item-price matching, say, item-prices):

//div[contains(concat(' ',@class,' '), ' item-price ') and contains(., '$')]
kjhughes
  • 98,039
  • 18
  • 159
  • 218
  • 1
    I like the telepathic support you are giving me by telling me about `contains()` because it is very valuable. I like the conjunctive syntax used above a bit more. So I'm torn on which to select as the answer because both are correct. – Terrence Brannon Oct 22 '13 at 14:08
  • 3
    You're welcome for the telepathic support. After nearly 5 years, perhaps you're now able to select one answer or the other to [**accept**](https://meta.stackexchange.com/q/5234/234215) now? :-) – kjhughes Aug 03 '18 at 11:42
6
//div[@class = 'item-price'][contains(., '$')]
Michael Kay
  • 147,186
  • 10
  • 83
  • 148
2

As per the HTML:

<div class="item-price">$0.99</div>

There is:

  • Only one value of the class attribute i.e. item-price
  • And the innerText starts with a $ sign.

So, to locate this element with respect to the value of the class attribute i.e. item-price and innerText content starting with a dollar sign ($) you can use either of the following solutions:

  • Using starts-with():

    //div[@class='item-price' and starts-with(., '$')]
    
  • Using contains():

    //div[@class='item-price' and contains(., '$')]
    
undetected Selenium
  • 151,581
  • 34
  • 225
  • 281