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