XPath contains (text (),'some string') ne fonctionne pas lorsqu'il est utilisé avec un nœud avec plus d'un sous-nœud de texte

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 donné l'élément racine...

Donc, le xpath que j'aurais 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 ne renvoie que L'élément Street et non L'élément Comment.

Le DOM fait de L'élément commentaire un élément composite avec quatre balises deux

[Text = 'XYZ'][BR][BR][Text = 'ABC'] 

Je suppose que la requête devrait toujours renvoyer l'élément car elle devrait trouver l'élément et exécuter contains dessus mais ce n'est pas le cas ... ...

La requête suivante renvoie l'élément mais elle renvoie beaucoup 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 seulement les éléments <Street/> et <Comment/> ?

188
demandé sur Piotr Dobrogost 2010-09-07 07:26:39

2 réponses

La balise <Comment> contient deux nœuds de texte et deux nœuds <br> en tant qu'enfants.

Votre expression xpath était

//*[contains(text(),'ABC')]

Pour décomposer cela,

  1. * est un sélecteur qui correspond à n'importe quel élément (c'est-à-dire tag) - il renvoie un ensemble de nœuds.
  2. les [] sont un conditionnel qui fonctionne sur chaque nœud individuel dans cet ensemble de nœuds. Il correspond si l'un des nœuds individuels sur lesquels il fonctionne correspond aux conditions à l'intérieur des parenthèses.
  3. text() est un sélecteur {[33] } qui correspond à tous les nœuds de texte qui sont des enfants du nœud de contexte - il renvoie un ensemble de nœuds.
  4. contains est une fonction qui fonctionne sur une chaîne. S'il est passé un ensemble de nœuds, l'ensemble de nœuds est converti en une chaîne en retournant 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 élément <Comment> - à savoir BLAH BLAH BLAH. Puisque cela ne correspond pas, vous n'obtenez pas de <Comment> dans votre résultat.

Vous devez changer cela en

//*[text()[contains(.,'ABC')]]
  1. * est un sélecteur qui correspond à n'importe quel élément (c'est-à-dire tag) - il renvoie un ensemble de nœuds.
  2. les [] externes sont un conditionnel qui fonctionne sur chaque nœud individuel dans cet ensemble de nœuds - ici, il fonctionne sur chaque élément du document.
  3. {[6] } est un sélecteur qui correspond à tous les nœuds de texte qui sont Enfants du nœud de contexte - il renvoie un ensemble de nœuds.
  4. les [] internes sont un conditionnel qui fonctionne sur chaque nœud dans cet ensemble de nœuds -- ici, chaque nœud de texte. Chaque nœud de texte individuel est le point de départ de tout chemin entre crochets, et peut également être appelé explicitement . dans les crochets. Il correspond si l'un des nœuds individuels sur lesquels il fonctionne correspond aux conditions à l'intérieur des parenthèses.
  5. contains est une fonction qui fonctionne sur une chaîne. Ici, il est passé un noeud de texte individuel (.). Comme il est passé le deuxième noeud de texte dans le <Comment> tag individuellement, il verra la chaîne 'ABC' et pourra la faire correspondre.
545
répondu Ken Bloom 2010-09-07 04:07:21

[contains(text(),'')] renvoie uniquement true ou false. Il ne retournera aucun élément de résultats.

6
répondu Ratna 2017-05-08 13:27:37