web-dev-qa-db-fra.com

Xpath: sélectionnez un div qui contient la classe AND dont l'élément enfant spécifique contient du texte

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>
22
Andrejs

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.

37
nwellnhof

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>'
6
SomeDude

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')]
6
Alex Payne

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.

3
Sami Kuhmonen