XPath: разница между точкой и текстом ()

Мой вопрос об особенностях использования точки и text() в XPath, Например, следующий find_element линии возвращает тот же элемент:

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

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

Так в чем же разница? Каковы преимущества и недостатки использования . а также text()?

2 ответа

Решение

Есть разница между . а также text(), но это различие может не появиться из-за вашего входного документа.

Если ваш входной документ выглядел так (самый простой документ, который вы можете себе представить, учитывая ваши выражения XPath)

Пример 1

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

затем //a[text()="Ask Question"] а также //a[.="Ask Question"] действительно вернуть точно такой же результат. Но рассмотрим другой входной документ, который выглядит как

Пример 2

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

где a элемент также имеет дочерний элемент other что следует сразу после "Задать вопрос". Учитывая этот второй входной документ, //a[text()="Ask Question"] по-прежнему возвращает a элемент, в то время как //a[.="Ask Question"] ничего не возвращает!


Это потому, что значение двух предикатов (все между [ а также ]) это отличается. [text()="Ask Question"] на самом деле означает: вернуть true, если любой из текстовых узлов элемента содержит именно текст "Задать вопрос". С другой стороны, [.="Ask Question"] означает: вернуть true, если строковое значение элемента идентично "Задать вопрос".

В модели XPath текст внутри элементов XML может быть разделен на несколько текстовых узлов, если другие элементы мешают тексту, как в примере 2 выше. Там other Элемент находится между "Задать вопрос" и символом новой строки, который также считается текстовым содержимым.

Чтобы сделать еще более четкий пример, рассмотрим в качестве входного документа:

Пример 3

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

Здесь a элемент содержит два текстовых узла: "Задать вопрос" и "больше текста", так как оба являются прямыми потомками a, Вы можете проверить это, запустив //a/text() на этот документ, который будет возвращаться (отдельные результаты, разделенные ----):

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

Итак, в таком сценарии, text() возвращает набор отдельных узлов, в то время как . в предикате оценивает конкатенацию строк всех текстовых узлов. Опять же, вы можете проверить это утверждение с помощью выражения пути //a[.='Ask Questionmore text'] который успешно вернет a элемент.


Наконец, имейте в виду, что некоторые функции XPath могут принимать только одну строку в качестве входных данных. Как указал в комментариях LarsH, если такая функция XPath (например, contains()) дана последовательность узлов, она будет обрабатывать только первый узел и молча игнорировать остальные.

Есть большая разница между dot (".") а также text():-

  • dot (".") в XPath называется "выражение элемента контекста", поскольку оно относится к элементу контекста. Это может быть соответствие с узлом (например, element, attribute, или же text node) или атомное значение (например, string, number, или же boolean). В то время как text() относится только к совпадению element text который в string форма.

  • dot (".") нотация - это текущий узел в DOM. Это будет объект типа Node при использовании XPath Функция text(), чтобы получить текст для элемента, получает текст только до первого внутреннего элемента. Если текст, который вы ищете, находится после внутреннего элемента, вы должны использовать текущий узел для поиска строки, а не XPath функция text()

Для примера:-

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

Здесь, если вы хотите найти якорь a элемент с помощью текстовой ссылки, вы должны использовать dot ("."), Потому что, если вы используете //a[contains(.,'link')] он находит якорь a элемент, но если вы используете //a[contains(text(),'link')] text() функция, похоже, не находит его.

Надеюсь, это поможет вам..:)

введите здесь описание изображения.Функция XPath text() находит элементы внутри текстового узла, а точка (.) находит элементы внутри или снаружи текстового узла. На снимке экрана с описанием изображения функция XPath text() найдет успех только в примере 2 DOM. В примере 1 DOM он не добьется успеха, потому что он расположен между тегами.

Кроме того, функция text () не будет успешной в примере 3 DOM, потому что успех не имеет прямого отношения к элементу. Вот демонстрационное видео, объясняющее разницу между текстом () и точкой (.) https://youtu.be/oi2Q7-0ZIBg

Другие вопросы по тегам