100 votes

XPath: différence entre le point et le texte()

Ma question est sur les spécificités de l'utilisation de la dot et de l' text() en XPath. Par exemple, à la suite d' find_element lignes retourne même élément:

driver.get('http://stackoverflow.com/')

driver.find_element_by_xpath('//a[text()="Ask Question"]')
driver.find_element_by_xpath('//a[.="Ask Question"]')

Quelle est donc la différence? Quels sont les avantages et les inconvénients de l'utilisation de . et text()?

161voto

Mathias Müller Points 16681

Il y a une différence entre . et text(), mais cette différence peut pas surface à cause de votre document d'entrée.

Si votre document d'entrée ressemblait (le plus simple document on peut l'imaginer, compte tenu de vos expressions XPath)

Exemple 1

<html>
  <a>Ask Question</a>
</html>

Ensuite, //a[text()="Ask Question"] et //a[.="Ask Question"] en effet de retour exactement le même résultat. Mais envisager un autre document d'entrée qui ressemble à

Exemple 2

<html>
  <a>Ask Question<other/>
  </a>
</html>

où l' a élément a aussi un enfant de l'élément other qui suit immédiatement après "Poser une Question". Compte tenu de cette deuxième document d'entrée, //a[text()="Ask Question"] renvoie toujours l' a , alors //a[.="Ask Question"] ne retourne rien!


C'est parce que le sens des deux prédicats (tout ce qui est entre [ et ]) est différent. [text()="Ask Question"] signifie en réalité: retourne true si l'un des nœuds de texte d'un élément contient exactement le texte "Poser une Question". D'autre part, [.="Ask Question"] moyen: retourne true si la chaîne de valeur de l'élément est identique à "Poser une Question".

Le XPath modèle, le texte à l'intérieur des éléments XML peut être divisée en un certain nombre de nœuds de texte si d'autres éléments d'interférer avec le texte, comme dans l'Exemple 2 ci-dessus. Là, l' other élément est entre "Poser une Question" et un caractère de saut de ligne qui compte aussi comme un contenu de texte.

Pour prendre un exemple encore plus net, considérer comme un document d'entrée:

Exemple 3

<a>Ask Question<other/>more text</a>

Ici, l' a élément contient en fait deux nœuds de texte, "Poser une Question" et "texte", puisque les deux sont les enfants directs d' a. Vous pouvez le tester en exécutant //a/text() sur ce document, qui sera de retour (résultats individuels séparés par ----):

Ask Question
-----------------------
more text

Donc, dans un tel scénario, text() renvoie un ensemble de nœuds individuels, tout en . dans un prédicat correspond à la concaténation de chaîne de tous les nœuds de texte. Encore une fois, vous pouvez tester cette réclamation auprès de l'expression de chemin d'accès //a[.='Ask Questionmore text'] qui va réussir à revenir l' a élément.


Enfin, gardez à l'esprit que certaines fonctions XPath ne pouvez prendre qu'une seule chaîne en entrée. Comme LarsH l'a souligné dans les commentaires, si une telle fonction XPath (par exemple, contains()) est donnée une séquence de nœuds, il ne traitera que le premier nœud et silencieusement ignorer le reste.

30voto

Saurabh Gaur Points 15926

Il y a une grande différence entre dot (".") et text() :-

  • L' dot (".") en XPath est appelé "élément de contexte l'expression" parce qu'il fait référence à l'élément de contexte. Ce pourrait être le match avec un nœud (comme un element, attributeou text node) ou une valeur atomique (comme un string, numberou boolean). Alors qu' text() se réfère à correspondre qu' element text qui est en string formulaire.

  • L' dot (".") notation est le nœud courant dans les DOM. Cela va être un objet de type Node, tout en Utilisant l' XPath de la fonction texte() pour obtenir le texte d'un élément obtient le texte jusqu'à la première intérieure de l'élément. Si le texte que vous cherchez est après l' intérieure de l'élément , vous devez utiliser le nœud actuel pour la recherche de la chaîne et non l' XPath text() fonction.

Pour un exemple :-

<a href="something.html">
  <img src="filename.gif">
  link
</a>

Ici, si vous voulez trouver d'ancrage a élément en utilisant le texte de lien, vous devez utiliser dot ("."). Parce que si vous utilisez //a[contains(.,'link')] il trouve le point d'ancrage a élément, mais si vous utilisez //a[contains(text(),'link')] le text() fonction ne semble pas à la trouver.

Espérons qu'il saura vous aider..:)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X