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?

HOE SENGKIANG
la source
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()
Jens Erat
la source
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
37

Ce dont vous avez besoin est l' following-siblingaxe XPath

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

Testez Xpath ici: http://www.xpathtester.com/obj/b55ec3ac-dfa4-4f44-81e8-f963ea4a0625

Stanley
la source
4
@HOESENGKIANG: vous devez cliquer sur la coche pour "accepter" cette réponse, ou celle qui répond le mieux à la question selon vous.
LarsH
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']
hr_117
la source
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.

Petr Janeček
la source
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

Bae Cheol Shin
la source
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.

Saleh Mahmood
la source