web-dev-qa-db-fra.com

XPath: Comment sélectionner des éléments en fonction de leur valeur?

Je suis nouveau à utiliser XPath et cela peut être une question de base. Veuillez supporter et aidez-moi à résoudre le problème. J'ai un fichier XML comme ceci:

<RootNode>
  <FirstChild>
    <Element attribute1="abc" attribute2="xyz">Data</Element>
  <FirstChild>
</RootNode>

Je peux valider la présence d'une balise <Element> avec:

// Element [@ attribut1 = "abc" et @ attribut2 = "xyz"]

Maintenant, je veux aussi vérifier la valeur de la balise pour la chaîne "Data". Pour y parvenir, on m'a dit d'utiliser:

// Element [@ attribut1 = "abc" et @ attribut2 = "xyz" et données]

Lorsque j'utilise l'expression ultérieure, j'obtiens l'erreur suivante:

Message d'échec d'assertion: aucun nœud ne correspond //Element[@attribute1="abc" and @attribute2="xyz" and Data]

Veuillez me donner votre avis si l’expression XPath que j’ai utilisée est valide. Si non, quelle sera l'expression XPath valide?

210
vcosk

La condition ci-dessous:

//Element[@attribute1="abc" and @attribute2="xyz" and Data]

vérifie l'existence de l'élément Data dans Element et non de la valeur de l'élément Data.

Au lieu de cela, vous pouvez utiliser

//Element[@attribute1="abc" and @attribute2="xyz" and text()="Data"]
310
Rashmi Pandit
//Element[@attribute1="abc" and @attribute2="xyz" and .="Data"]

La raison pour laquelle j'ajoute cette réponse est que je veux expliquer la relation entre . et text().

La première chose est lors de l'utilisation de [], il n'y a que deux types de données:

  1. *[number] pour sélectionner un nœud dans un ensemble de nœuds
  2. *[bool] pour filtrer un ensemble de nœuds d'un ensemble de nœuds

Dans ce cas, la valeur est évaluée à booléen par la fonction boolean(), et il existe une règle:

Les filtres sont toujours évalués par rapport à un contexte.

Lorsque vous devez comparer text() ou . avec une chaîne "Data", il utilise d'abord la fonction string() pour les transformer en type chaîne, ce qui donne un résultat booléen.

Il y a deux règles importantes sur string():

  1. La fonction string() convertit un ensemble de nœuds en une chaîne en renvoyant la valeur de chaîne du premier nœud de l'ensemble de nœuds, ce qui peut dans certains cas produire des résultats inattendus.

    text() est le chemin relatif qui retourne un ensemble de nœuds contenant tout le nœud de texte du nœud actuel (nœud de contexte), comme ["Data"]. Lorsqu'il est évalué par string(["Data"]), il renvoie le premier nœud de l'ensemble de nœuds. Vous obtenez donc "Données" uniquement lorsqu'il n'y a qu'un seul nœud de texte dans l'ensemble de nœuds.

  2. Si vous voulez que la fonction string() concatène tout le texte enfant, vous devez alors passer un seul nœud au lieu d'un ensemble de nœuds.

    Par exemple, nous obtenons un ensemble de nœuds ['a', 'b'], vous pouvez y passer le nœud parent à string(parent), cela retournera 'ab' et la cause string(.) dans votre cas, vous renverrez une chaîne concaténée "Data".

Les deux méthodes obtiendront le même résultat uniquement lorsqu'il existe un nœud de texte.

19
宏杰李