Quel est le XPath correct pour choisir les attributs qui contiennent «foo»?


176

Compte tenu de ce XML, ce que XPath renvoie tous les éléments dont l' propattribut contient Foo(les trois premiers nœuds):

<bla>
 <a prop="Foo1"/>
 <a prop="Foo2"/>
 <a prop="3Foo"/>
 <a prop="Bar"/>
</bla>

1
Pourquoi tout le monde regarde-t-il l'attribut "prop"? Ai-je oublié quelque chose? Il dit simplement obtenir les trois premiers nœuds.

6
Tout le monde regarde l'attribut prop parce que c'est ce qui a été demandé. Récupère tous les nœuds où prop contient "Foo". Ajoutez <a prop="Foo5" /> et vous verrez pourquoi ce n'est pas seulement "les trois premiers nœuds" ..
erlando

La question dans le corps est mal formulée, quel que soit le titre. Foo peut-il vraiment être dans n'importe quel attribut prop, ou voulez-vous sérieusement simplement les trois premiers nœuds?

3
Oui, veuillez vous référer au titre (et n'hésitez pas à le modifier).
ripper234

Si vous avez besoin d'une comparaison insensible à la casse, voir trouver un élément dont l'attribut contient un texte insensible à la casse
Michael Freidgeim

Réponses:


307
//a[contains(@prop,'Foo')]

Fonctionne si j'utilise ce XML pour obtenir des résultats.

<bla>
 <a prop="Foo1">a</a>
 <a prop="Foo2">b</a>
 <a prop="3Foo">c</a>
 <a prop="Bar">a</a>
</bla>

Edit: Une autre chose à noter est que si XPath ci-dessus retournera la bonne réponse pour ce xml particulier, si vous voulez vous garantir que vous n'obtiendrez que les éléments "a" dans l'élément "bla", vous devriez, comme d'autres l'ont mentionné, également utiliser

/bla/a[contains(@prop,'Foo')]

Cela vous recherchera tous les éléments "a" dans tout votre document XML, qu'ils soient imbriqués dans un élément "bla"

//a[contains(@prop,'Foo')]  

J'ai ajouté ceci par souci de rigueur et dans l'esprit du stackoverflow. :)


3
xmlme.comredirige maintenant vers un autre hôte et ne semble pas héberger l'outil ou quelque chose de similaire.
jpmc26

26

Ce XPath vous donnera tous les nœuds qui ont des attributs contenant 'Foo' quel que soit le nom du nœud ou le nom de l'attribut:

//attribute::*[contains(., 'Foo')]/..

Bien sûr, si vous êtes plus intéressé par le contenu de l'attribut lui-même, et pas nécessairement par son nœud parent, supprimez simplement le / ..

//attribute::*[contains(., 'Foo')]

2
Pour tous les nœuds//@*[contains(., 'Foo')]
aliopi

16
descendant-or-self::*[contains(@prop,'Foo')]

Ou:

/bla/a[contains(@prop,'Foo')]

Ou:

/bla/a[position() <= 3]

Disséqué:

descendant-or-self::

L'Axe - recherchez dans chaque nœud en dessous et le nœud lui-même. Il vaut souvent mieux dire ceci que //. J'ai rencontré des implémentations où // signifie n'importe où (décendant ou self du nœud racine). L'autre utilise l'axe par défaut.

* or /bla/a

La balise - une correspondance générique, et / bla / a est un chemin absolu.

[contains(@prop,'Foo')] or [position() <= 3]

La condition entre []. @prop est un raccourci pour attribut :: prop, car attribut est un autre axe de recherche. Vous pouvez également sélectionner les 3 premiers en utilisant la fonction position ().


6

John C est le plus proche, mais XPath est sensible à la casse, donc le XPath correct serait:

/bla/a[contains(@prop, 'Foo')]

4

Avez-vous essayé quelque chose comme:

// a [contient (@prop, "Foo")]

Je n'ai jamais utilisé la fonction contient auparavant, mais je soupçonne qu'elle devrait fonctionner comme annoncé ...


@toddk ... vous avez ciblé un attribut inexistant: @foo. Vous voudriez cibler @prop ;-)
Metro Smurf

4

Si vous devez également faire correspondre le contenu du lien lui-même, utilisez text ():

//a[contains(@href,"/some_link")][text()="Click here"]



1

Pour le code ci-dessus ... // * [contains (@ prop, 'foo')]


ceci est pour tout élément avec foo in, mais l'attribut doit être "prop"
digiguru

1

essaye ça:

// a [contient (@ prop, 'foo')]

qui devrait fonctionner pour toutes les balises "a" du document

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.