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

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

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

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

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

Ответы

Ответ 1

Существует разница между . и 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"] на самом деле означает: return true, если какой-либо из текстовых узлов элемента содержит точно текст "Ask Question" . С другой стороны, [.="Ask Question"] означает: return true, если строковое значение элемента идентично "Ask Question" .

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

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

Пример 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()) задана последовательность узлов, она обрабатывает только первый node и молча игнорирует остальные.

Ответ 2

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

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

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

Пример: -

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

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

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

Ответ 3

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

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