Avec l'aide de this SO question j'ai un xpath presque fonctionnel:
//div[contains(@class, 'measure-tab') and contains(., 'someText')]
Cependant, cela donne deux divs
: dans l'un c'est l'enfant td
qui a un texte, l'autre c'est l'enfant span
.
Comment puis-je le réduire à celui avec le 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>
Pour trouver un div
d'une certaine classe contenant un span
à n'importe quelle profondeur contenant du texte, essayez:
//div[contains(@class, 'measure-tab') and contains(.//span, 'someText')]
Cela dit, cette solution semble extrêmement fragile. Si la table contient un span
avec le texte que vous recherchez, le div
contenant la table sera également mis en correspondance. Je suggérerais de trouver un moyen plus robuste de filtrer les éléments. Par exemple, en utilisant des identifiants ou une structure de document de niveau supérieur.
Vous pouvez utiliser le xpath:
//div[@class="measure-tab" and .//span[contains(., "someText")]]
Contribution :
<root>
<div class="measure-tab">
<td> someText</td>
</div>
<div class="measure-tab">
<div>
<div2>
<span>someText2</span>
</div2>
</div>
</div>
</root>
Sortie:
Element='<div class="measure-tab">
<div>
<div2>
<span>someText2</span>
</div2>
</div>
</div>'
Vous pouvez utiliser ancestor
. Je trouve que c'est plus facile à lire parce que l'élément que vous sélectionnez se trouve à la fin du chemin.
//span[contains(text(),'someText')]/ancestor::div[contains(@class, 'measure-tab')]
Vous pouvez modifier votre deuxième condition pour vérifier uniquement l'élément span:
...and contains(div/span, 'someText')]
Si la plage n’est pas toujours dans une autre division, vous pouvez également utiliser
...and contains(.//span, 'someText')]
Ceci recherche la portée n'importe où dans la div.