web-dev-qa-db-fra.com

XPath: sélection du premier élément avec un attribut spécifique

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']

276
ripper234

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)

403
Jonathan Fingland

/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.

165
tkurki

Pour expliquer la réponse de Jonathan Fingland:

  • plusieurs conditions dans le même prédicat ([position()=1 and @location='US']) doivent être vraies dans son ensemble
  • plusieurs conditions dans des prédicats consécutifs ([position()=1][@location='US']) doivent être vraies ne après l'autre
  • cela implique que [position()=1][@location='US']! = [@location='US'][position()=1]
    while [position()=1 and @location='US'] == [@location='US' and position()=1]
  • indice: un seul [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.

45
Tomalak

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]
12
Gee-Bee
    <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]
8
iZian

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.

3
Mounika Medipelli

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]
1
metal

par ex.

<input b="demo">

Et

(input[@b='demo'])[1]
0
SenthilKumarP