Comment sélectionner un nœud à l'aide de XPath si le nœud frère a une valeur spécifique?


88

J'ai le document suivant:

<a>
  <bb>abc</bb>
  <cc>ccc</cc>
  <dd>ddd</dd>
</a>
<a>
  <bb>zz</bb>
  <cc>1</cc>
  <dd>2</dd>
</a>

Comment puis-je obtenir la valeur de l' <cc>utilisation de XPath si <bb>c'est le cas zz?


1
le problème est que je sais comment accéder à un nœud spécifique, mais je n'ai aucune idée d'accéder à un nœud si un frère a une valeur spécifique. Cela peut-il être quelque chose comme ceci / a / cc / contains (/ a / bb = 'zz')?
HOE SENGKIANG

Réponses:


100

Vous ne savez pas pourquoi tout le monde demande des frères et sœurs, vous pouvez également vérifier les <bb/>éléments correspondant au prédicat du <a/>prédicat de:

//a[bb/text() = "zz"]/cc/text()

24
"Je ne sais pas pourquoi tout le monde demande des frères et sœurs" : Peut-être parce que la question s'adressait aux frères et sœurs .. ;-)
hr_117

4
Il semble que je n'ai pas lu le titre. :) La réponse reste valable de toute façon.
Jens Erat

2
Vos questions de réponse pour les frères et sœurs aussi. Vous n'avez simplement pas utilisé d' *-siblingaxe. +1 cependant.
LarsH du

Cela ne répond pas à la question mais cela répond à ma question réelle que j'ai mal formulée. Merci!
User9213


23

Q: Comment sélectionner un nœud à l'aide de XPath si le nœud frère a une valeur spécifique?
Comme il n'y a que des "axes XPath" pour les frères suivants et les frères précédents, vous pouvez utiliser l'un d'entre eux si la position est fixe.

Mais mieux: recherchez où ccle parent a un enfant bbavec une valeur 'zz':

//cc[../bb='zz']

6
Soit ça, soit //a[bb = 'zz']/cc.
Tomalak du

Je ne sais pas ce que vous entendez par «seulement« XPath Axes »pour le frère suivant et le frère précédent». Faites-vous référence au fait qu'il n'y a pas d'axe unique pour tous les frères et sœurs?
LarsH

@LarsH: Oui désolé, (excusez mon mauvais anglais :-() - c'est ce que j'essayais de dire. (Parce que la question était pour les frères et sœurs.)
hr_117

6

Tout d'abord, votre exemple n'est pas un XML bien formé. Compte tenu de cela et que vous ne décrivez pas très bien vos intentions (que voulez-vous sélectionner exactement à quelle condition?), Je suppose que vous voulez faire ceci:

//cc[preceding-sibling::bb[text()="zz"]]/text()

Il sélectionne

TEXT VALUES OF ALL <CC> ELEMENTS
//cc                                    /text()
    THAT HAVE A PRECEDING SIBLING <BB>
    [preceding-sibling::bb             ]
                          THAT HAS TEXT VALUE EQUAL TO "zz"
                          [text()="zz"]

Vous pourriez écrire est aussi comme

//bb[text()="zz"]/following-sibling::cc/text()

Veuillez regarder la spécification , elle contient des exemples très lisibles dont vous apprendrez beaucoup.


1
@LarsH Merci pour la correction de "non valide" à "pas bien formé". J'ai appris quelque chose de nouveau aujourd'hui.
Petr Janeček

4
//a/cc[../bb='zz']/text()

// a: sélectionne tous les éléments 'a', peu importe où ils se trouvent.

// a / cc: Sélectionne les éléments 'cc' qui sont les enfants de l'élément 'a' (peu importe où se trouve a).

..: sélectionne le parent du nœud actuel.

[../bb='zz ']: où la valeur de l'élément frère' bb 'est zz.

Référence: http://www.w3schools.com/xsl/xpath_syntax.asp


4

Une autre solution à ce problème est

//bb[contains(.,'zz')]/../cc/text()

Explication : Tout ce bbqui contient une 'zz'chaîne dans tous les nœuds enfants du bbnœud parent de cette bbutilisation .., maintenant que nous pouvons accéder au cctexte de retour.

J'espère que cette explication n'est pas complexe.

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.