mh3982
mh3982

Reputation: 97

Xpath with multiple descendant conditions

I have an HTML file that looks like:

<div id="products">
   <div class="product">
      <span class="productheader">Product 1</span>
      <input type="checkbox" />
   </div>
   <div class="product">
      <span class="productheader">Product 2</span>
      <div class="selected_value and_other value plus one value">
         <input type="checkbox" checked="checked" />
      </div>
   </div>
   <div class="product">
      <span class="productheader">Product 3</span>
      <span class="hidden">
         <div class="selected_value and_other value">
            <input type="checkbox" checked="checked" />
         </div>
      </span>
   </div>
</div>

I'd like to have the value from header where:

so, only the second productheader value (Product 2) should be the result.

How should the correct xpath look like?

Tried many things, but none works. Most closely:

//div[contains(@class, 'product')]//*[descendant::div[contains(@class ,"selected_value")]]

Problem is that this does not account that it may not be hidden!

Upvotes: 2

Views: 783

Answers (2)

E.Wiest
E.Wiest

Reputation: 5905

To complete @supputuri's answer, more (5) XPath options (from shortest to longest):

//input[@checked][not(ancestor::span)]/preceding::span[1]/text()
//div[@class="product"][.//@checked and not(span[@class="hidden"])]/*[1]/text()
//input[@checked][not(ancestor::span)]/ancestor::div[@class="product"]/*[1]/text()
//input[@checked][not(ancestor::span)]/ancestor::div[@class="product"]/*[1]/text()
//span[@class="productheader"][following::input[1][@checked][not(ancestor::span)]]/text()

Upvotes: 1

supputuri
supputuri

Reputation: 14135

You can do it in different ways as shown below. Option 1:

//div[starts-with(@class,'selected_value')][not(parent::span[@class='hidden'])]/preceding-sibling::span/text()

Option 2: simplest

//div[starts-with(@class,'selected_value')]/preceding-sibling::span/text()

Option 3: If you want to use the span class then follow this.

//div[starts-with(@class,'selected_value')]/preceding-sibling::span[@class='productheader']/text()

Upvotes: 1

Related Questions