Le XPath bookstore/book[1]
sélectionne le premier noeud de livre sous bookstore
.
Comment puis-je sélectionner le premier nœud qui correspond à une condition plus compliquée, par ex. le premier noeud qui correspond à /bookstore/book[@location='US']
utiliser (/bookstore/book[@location='US'])[1]
Cela va d'abord obtenir les éléments du livre avec l'attribut location égal à 'US'. Ensuite, il sélectionnera le premier noeud de cet ensemble. Notez l'utilisation de parenthèses, requises par certaines implémentations.
(notez que ce n'est pas la même chose que /bookstore/book[1][@location='US']
sauf si le premier élément a aussi l'attribut location)
/bookstore/book[@location='US'][1]
ne fonctionne qu'avec une structure simple.
Ajoutez un peu plus de structure et ça casse.
Avec
<bookstore>
<category>
<book location="US">A1</book>
<book location="FIN">A2</book>
</category>
<category>
<book location="FIN">B1</book>
<book location="US">B2</book>
</category>
</bookstore>
/bookstore/category/book[@location='US'][1]
donne
<book location="US">A1</book>
<book location="US">B2</book>
pas "le premier noeud qui correspond à une condition plus compliquée". /bookstore/category/book[@location='US'][2]
ne renvoie rien.
Avec des parenthèses, vous pouvez obtenir le résultat auquel la question initiale était destinée:
(/bookstore/category/book[@location='US'])[1]
donne
<book location="US">A1</book>
et (/bookstore/category/book[@location='US'])[2]
fonctionne comme prévu.
Pour expliquer la réponse de Jonathan Fingland:
[position()=1 and @location='US']
) doivent être vraies dans son ensemble[position()=1][@location='US']
) doivent être vraies ne après l'autre[position()=1][@location='US']
! = [@location='US'][position()=1]
[position()=1 and @location='US']
== [@location='US' and position()=1]
[position()=1]
peut être abrégé en [1]
Vous pouvez créer des expressions complexes dans les prédicats avec les opérateurs booléens "and
" et "or
", ainsi qu'avec les fonctions booléennes XPath not()
, true()
et false()
. . De plus, vous pouvez envelopper les sous-expressions entre parenthèses.
Le moyen le plus simple de trouver le premier noeud de livre en anglais (dans l'ensemble du document), en prenant en considération un fichier XML structuré plus complexe, tel que:
<bookstore>
<category>
<book location="US">A1</book>
<book location="FIN">A2</book>
</category>
<category>
<book location="FIN">B1</book>
<book location="US">B2</book>
</category>
</bookstore>
est l'expression xpath:
/descendant::book[@location='US'][1]
<bookstore>
<book location="US">A1</book>
<category>
<book location="US">B1</book>
<book location="FIN">B2</book>
</category>
<section>
<book location="FIN">C1</book>
<book location="US">C2</book>
</section>
</bookstore>
Donc, compte tenu de ce qui précède; vous pouvez sélectionner le premier livre avec
(//book[@location='US'])[1]
Et ceci trouvera le premier endroit n'importe où qui a un emplacement US. [A1]
//book[@location='US']
Renvoie le groupe de noeuds avec tous les livres d'emplacement US. [A1, B1, C2]
(//category/book[@location='US'])[1]
Renverrait le premier emplacement de livre US qui existe dans une catégorie n'importe où dans le document. [B1]
(/bookstore//book[@location='US'])[1]
renverra le premier livre avec l'emplacement US qui existe n'importe où sous la librairie d'éléments racine; rendant la partie librairie vraiment redondante. [A1]
En réponse directe:
/bookstore/book[@location='US'][1]
Vous renverra le premier noeud de l'élément book avec l'emplacement US situé sous librairie [A1]
Incidemment, si vous vouliez, dans cet exemple, trouver le premier livre américain qui n'était pas un enfant direct de la librairie:
(/bookstore/*//book[@location='US'])[1]
Utilisez l'index pour obtenir le nœud souhaité si xpath est compliqué ou s'il existe plusieurs nœuds avec le même xpath.
ex: (// librairie [@location = 'US']) [index]
vous pouvez donner au numéro quel nœud vous voulez.
si un espace de noms est fourni sur le XML donné, il est préférable de l'utiliser.
(/*[local-name() ='bookstore']/*[local-name()='book'][@location='US'])[1]
par ex.
<input b="demo">
Et
(input[@b='demo'])[1]