J'ai un petit problème avec Xpath contient avec dom4j ...
Disons que mon XML est
<Home>
<Addr>
<Street>ABC</Street>
<Number>5</Number>
<Comment>BLAH BLAH BLAH <br/><br/>ABC</Comment>
</Addr>
</Home>
Disons que je veux trouver tous les nœuds qui ont ABC dans le texte étant donné l'élément racine ...
Ainsi, le xpath que j'aurais eu besoin d'écrire serait
//*[contains(text(),'ABC')]
Cependant, ce n'est pas ce que Dom4j renvoie .... est-ce un problème dom4j ou ma compréhension du fonctionnement de xpath. puisque cette requête renvoie uniquement l'élément Street et non l'élément Comment.
Le DOM fait de l'élément Comment un élément composite avec quatre balises deux
[Text = 'XYZ'][BR][BR][Text = 'ABC']
Je suppose que la requête doit toujours renvoyer l'élément car elle doit trouver l'élément et exécuter contient dessus, mais il ne le fait pas ... ...
la requête suivante renvoie l'élément mais elle renvoie bien plus que l'élément, elle renvoie également les éléments parents ... ce qui n'est pas souhaitable pour le problème ...
//*[contains(text(),'ABC')]
Est-ce que quelqu'un connaît la requête xpath qui retournerait uniquement les éléments <Street/>
et <Comment/>
?
//*[contains(text(),'ABC')]
ne renvoie que l'<Street>
élément. Il ne retourne aucun ancêtre de<Street>
ou<Comment>
.Réponses:
La
<Comment>
balise contient deux nœuds de texte et deux<br>
nœuds en tant qu'enfants.Votre expression xpath était
Pour décomposer cela,
*
est un sélecteur qui correspond à n'importe quel élément (c'est-à-dire une balise) - il renvoie un ensemble de nœuds.[]
s'agit d'une conditionnelle qui fonctionne sur chaque nœud individuel de cet ensemble de nœuds. Il correspond si l'un des nœuds individuels sur lesquels il opère correspond aux conditions à l'intérieur des crochets.text()
est un sélecteur qui correspond à tous les nœuds de texte qui sont des enfants du nœud de contexte - il renvoie un ensemble de nœuds.contains
est une fonction qui opère sur une chaîne. Si un ensemble de nœuds lui est transmis, l'ensemble de nœuds est converti en chaîne en renvoyant la valeur de chaîne du nœud dans l'ensemble de nœuds qui est le premier dans l'ordre du document . Par conséquent, il ne peut correspondre qu'au premier nœud de texte de votre<Comment>
élément, à savoirBLAH BLAH BLAH
. Comme cela ne correspond pas, vous n'obtenez pas<Comment>
de résultat dans vos résultats.Vous devez changer cela en
*
est un sélecteur qui correspond à n'importe quel élément (c'est-à-dire une balise) - il renvoie un ensemble de nœuds.[]
est une condition qui fonctionne sur chaque nœud individuel de cet ensemble de nœuds - ici, il fonctionne sur chaque élément du document.text()
est un sélecteur qui correspond à tous les nœuds de texte qui sont des enfants du nœud de contexte - il renvoie un ensemble de nœuds.[]
est une condition qui opère sur chaque nœud de cet ensemble de nœuds - ici chaque nœud de texte individuel. Chaque nœud de texte individuel est le point de départ de tout chemin entre crochets et peut également être désigné explicitement comme.
entre crochets. Il correspond si l'un des nœuds individuels sur lesquels il opère correspond aux conditions à l'intérieur des crochets.contains
est une fonction qui opère sur une chaîne. Ici, il est passé un nœud de texte individuel (.
). Puisqu'il est passé le deuxième nœud de texte dans la<Comment>
balise individuellement, il verra la'ABC'
chaîne et pourra la faire correspondre.la source
//*[contains(., 'ABC')]
. J'avais toujours utilisé le modèle donné par Mike Milkin, pensant qu'il était plus approprié, mais simplement fairecontains
dans le contexte actuel semble être ce que je veux le plus souvent.[contains(text(),'')]
renvoie uniquement vrai ou faux. Il ne renverra aucun résultat d'élément.la source
contains(text(),'JB-')
ce n'est pas du travail!conatains
prend deux chaînes comme arguments -contains(**string**, **string**)
! text () n'est pas une chaîne , est une fonction!Le document XML:
L'expression XPath:
//*
correspond à tout élément descendant du nœud racine . Autrement dit, tout élément, sauf le nœud racine.[...]
est un prédicat , il filtre l'ensemble de nœuds. Elle retourne les nœuds pour lesquels...
esttrue
:contains('haystack', 'needle')
renvoietrue
sihaystack
contientneedle
:Mais
contains()
prend une chaîne comme premier paramètre. Et ce sont des nœuds passés. Pour gérer cela, chaque nœud ou ensemble de nœuds transmis en tant que premier paramètre est converti en chaîne par lastring()
fonction:string()
retourne la fonctionstring-value
du premier nœud :string-value
d'un nœud d'élément :string-value
d'un nœud de texte :Donc, fondamentalement,
string-value
tout le texte est contenu dans un nœud (concaténation de tous les nœuds de texte descendants).text()
est un test de nœud qui correspond à n'importe quel nœud de texte:Cela dit,
//*[contains(text(), 'ABC')]
correspond à tout élément (sauf le nœud racine), dont le premier nœud de texte contientABC
. Depuistext()
retourne un ensemble de nœuds qui contient tous les nœuds de texte enfant du nœud de contexte (par rapport auxquels une expression est évaluée). Maiscontains()
ne prend que le premier. Donc, pour le document au-dessus du chemin correspond à l'Street
élément.L'expression suivante
//*[text()[contains(., 'ABC')]]
correspond à tout élément (mais le nœud racine) qui contient au moins un nœud de texte enfantABC
..
représente le nœud de contexte. Dans ce cas, il s'agit d'un nœud de texte enfant de tout élément sauf le nœud racine. Donc, pour le document au-dessus, le chemin correspondStreet
auxComment
éléments et.Maintenant,
//*[contains(., 'ABC')]
correspond à tout élément (mais le nœud racine) qui contientABC
(dans la concaténation des nœuds de texte descendants). Pour le document ci-dessus, il correspond aux élémentsHome
, theAddr
, theStreet
etComment
. En tant que tel,//*[contains(., 'BLAH ABC')]
correspond à laHome
, lesAddr
, et lesComment
éléments.la source
Cela m'a pris un peu de temps mais j'ai finalement compris. Le xpath personnalisé qui contient du texte ci-dessous a parfaitement fonctionné pour moi.
la source
contains(text(),'JB-')
ce n'est pas du travail!conatains
prend deux chaînes comme arguments -contains(**string**, **string**)
! text () n'est pas une chaîne , est une fonction!La réponse acceptée renverra également tous les nœuds parents. Pour obtenir uniquement les nœuds réels avec ABC même si la chaîne est après
:
la source
Retour
la source