Reputation: 97
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
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
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