XPath: sélectionnez le nœud de texte

150

Avoir le XML suivant:

<node>Text1<subnode/>text2</node>

Comment sélectionner le premier ou le deuxième nœud de texte via XPath?

Quelque chose comme ça:

/node/text()[2]

bien sûr ne fonctionne pas car c'est le résultat fusionné de chaque texte à l'intérieur du nœud.

noyau
la source
11
Vous avez écrit: /node/text()[2][...] ne fonctionne pas parce que c'est le résultat fusionné de chaque texte à l'intérieur du nœud C'est faux: cela signifie le deuxième nœud de texte enfant de nodel'élément racine . La valeur de la chaîne (concaténation des nœuds de texte descendants) seraitstring(/node)
Vous voulez dire que la requête Xpath devrait fonctionner? Eh bien, je suppose que j'ai un autre problème ailleurs. ;) Merci!
noyau
Bonne question, +1. Voir ma réponse pour une explication et plusieurs expressions XPath qui sélectionnent tout ou un enfant de nœud de texte spécifique de l'élément supérieur.
Dimitre Novatchev

Réponses:

183

Avoir le XML suivant:

<node>Text1<subnode/>text2</node> 

Comment sélectionner le premier ou le deuxième nœud de texte via XPath?

Utilisez :

/node/text()

Ceci sélectionne tous les enfants de noeud de texte de l'élément supérieur (nommé «noeud») du document XML.

/node/text()[1]

Ceci sélectionne le premier enfant de noeud de texte de l'élément supérieur (nommé «noeud») du document XML.

/node/text()[2]

Ceci sélectionne le deuxième enfant de noeud de texte de l'élément supérieur (nommé «noeud») du document XML.

/node/text()[someInteger]

Cela sélectionne le nœud de texte someInteger-ième enfant de l'élément supérieur (nommé "nœud") du document XML. C'est équivalent à l'expression XPath suivante:

/node/text()[position() = someInteger]
Dimitre Novatchev
la source
@NaftuliTzviKay: Cela signifie que Chrome est cassé. /node[2]ne doit sélectionner aucun nœud si le document XML source est bien formé. Par définition, dans un document XML bien formé, il n'y a qu'un seul élément supérieur - également connu sous le nom dedocument-element
Dimitre Novatchev
1
Cela fonctionne-t-il en PHP? J'essaie de parcourir uniquement les nœuds de texte, même ceux situés entre un ensemble de balises. Le problème est que le contenu de plusieurs nœuds de texte est brisé ensemble, indépendamment des balises. Utilisation de //*[text()]toute façon. /html/text()ne marche pas.
Aaron Gillion
2
@AaronGillion, Oui, AFAIK PHP a une évaluation XPath 1.0 fonctionnant correctement. Notez que /html/text()ne sélectionne pas tous les nœuds de texte dans le document - uniquement les nœuds de texte qui sont des enfants (et non des descendants) de l' htmlélément supérieur . Vous voulez probablement /html//text() . Une certaine connaissance et compréhension de XPath est généralement requise pour construire des expressions XPath.
Dimitre Novatchev
Merci. J'ai découvert le truc du double slash il y a un peu!
Aaron Gillion
@AaronGillion, vous êtes les bienvenus. Vous pouvez apprendre les bases de XPath 1.0 et 2.0 dans le module 2 de cette formation en ligne: pluralsight.com/courses/xslt-foundations-part1
Dimitre Novatchev
29

votre xpath devrait fonctionner. J'ai testé votre xpath et le mien dans l'implémentation MarkLogic et Zorba Xquery / Xpath.

Les deux devraient fonctionner.

/node/child::text()[1] - should return Text1
/node/child::text()[2] - should return text2


/node/text()[1] - should return Text1
/node/text()[2] - should return text2
kadalamittai
la source