Ответ 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 и молча игнорирует остальные.