Reputation: 11981
With the help of this SO question I have an almost working xpath:
//div[contains(@class, 'measure-tab') and contains(., 'someText')]
However this gets two divs
: in one it's the child td
that has someText, the other it's child span
.
How do I narrow it down to the one with the span
?
<div class="measure-tab">
<!-- table html omitted -->
<td> someText</td>
</div>
<div class="measure-tab"> <-- I want to select this div (and use contains @class)
<div>
<span> someText</span> <-- that contains a deeply nested span with this text
</div>
</div>
Upvotes: 103
Views: 337310
Reputation: 2148
You can simply do it this way:
//div[contains(text(),'someText')][@class='measure-tab']
This XPath
expression will select all div
elements in the DOM that contain the text 'someText' and have a class
attribute with the value 'measure-tab'.
Upvotes: 0
Reputation: 754
You can use ancestor
. I find that this is easier to read because the element you are actually selecting is at the end of the path.
//span[contains(text(),'someText')]/ancestor::div[contains(@class, 'measure-tab')]
Upvotes: 27
Reputation: 14238
You could use the xpath :
//div[@class="measure-tab" and .//span[contains(., "someText")]]
Input :
<root>
<div class="measure-tab">
<td> someText</td>
</div>
<div class="measure-tab">
<div>
<div2>
<span>someText2</span>
</div2>
</div>
</div>
</root>
Output :
Element='<div class="measure-tab">
<div>
<div2>
<span>someText2</span>
</div2>
</div>
</div>'
Upvotes: 21
Reputation: 31203
You can change your second condition to check only the span element:
...and contains(div/span, 'someText')]
If the span isn't always inside another div you can also use
...and contains(.//span, 'someText')]
This searches for the span anywhere inside the div.
Upvotes: 3
Reputation: 33658
To find a div
of a certain class that contains a span
at any depth containing certain text, try:
//div[contains(@class, 'measure-tab') and contains(.//span, 'someText')]
That said, this solution looks extremely fragile. If the table happens to contain a span
with the text you're looking for, the div
containing the table will be matched, too. I'd suggest to find a more robust way of filtering the elements. For example by using IDs or top-level document structure.
Upvotes: 158