问题描述
我的问题是关于在 XPath
中使用点和 text()
的细节.例如,以下 find_element
行返回相同的元素:
My question is about specifics of using dot and text()
in XPath
. For example, following find_element
lines returns same element:
driver.get('http://stackoverflow.com/')
driver.find_element_by_xpath('//a[text()="Ask Question"]')
driver.find_element_by_xpath('//a[.="Ask Question"]')
那么有什么区别呢?使用 .
和 text()
的优点和缺点是什么?
So what is the difference? What are the benefits and drawbacks of using .
and text()
?
推荐答案
.
和 text()
之间存在差异,但这种差异可能不会因为您的输入文档.
There is a difference between .
and text()
, but this difference might not surface because of your input document.
如果您的输入文档看起来像(根据您的 XPath 表达式可以想象的最简单的文档)
If your input document looked like (the simplest document one can imagine given your XPath expressions)
示例 1
<html>
<a>Ask Question</a>
</html>
然后 //a[text()="Ask Question"]
和 //a[.="Ask Question"]
确实返回完全相同的结果.但是考虑一个不同的输入文档,它看起来像
Then //a[text()="Ask Question"]
and //a[.="Ask Question"]
indeed return exactly the same result. But consider a different input document that looks like
示例 2
<html>
<a>Ask Question<other/>
</a>
</html>
其中 a
元素还有一个子元素 other
紧跟在Ask Question"之后.给定第二个输入文档,//a[text()="Ask Question"]
仍然返回 a
元素,而 //a[.="提问"]
不返回任何内容!
where the a
element also has a child element other
that follows immediately after "Ask Question". Given this second input document, //a[text()="Ask Question"]
still returns the a
element, while //a[.="Ask Question"]
does not return anything!
这是因为两个谓词([
和 ]
之间的所有内容)的含义不同.[text()="Ask Question"]
实际上的意思是:如果元素的任何文本节点正好包含文本Ask Question",则返回 true.另一方面,[.="Ask Question"]
表示:如果元素的字符串值与Ask Question"相同,则返回true.
This is because the meaning of the two predicates (everything between [
and ]
) is different. [text()="Ask Question"]
actually means: return true if any of the text nodes of an element contains exactly the text "Ask Question". On the other hand, [.="Ask Question"]
means: return true if the string value of an element is identical to "Ask Question".
在 XPath 模型中,如果其他元素干扰文本,XML 元素内的文本可以被划分为多个文本节点,如上面的示例 2.在那里,other
元素位于Ask Question"和一个也算作文本内容的换行符之间.
In the XPath model, text inside XML elements can be partitioned into a number of text nodes if other elements interfere with the text, as in Example 2 above. There, the other
element is between "Ask Question" and a newline character that also counts as text content.
举一个更清楚的例子,将其视为输入文档:
To make an even clearer example, consider as an input document:
示例 3
<a>Ask Question<other/>more text</a>
这里,a
元素实际上包含两个文本节点,Ask Question"和more text",因为它们都是 a的直接子节点代码>.您可以通过在此文档上运行
//a/text()
来测试这一点,它将返回(由 ----
分隔的单个结果):
Here, the a
element actually contains two text nodes, "Ask Question" and "more text", since both are direct children of a
. You can test this by running //a/text()
on this document, which will return (individual results separated by ----
):
Ask Question
-----------------------
more text
因此,在这种情况下,text()
返回一组单个节点,而谓词中的 .
计算结果为所有文本节点的字符串连接.同样,您可以使用路径表达式 //a[.='Ask Questionmore text']
测试此声明,它将成功返回 a
元素.
So, in such a scenario, text()
returns a set of individual nodes, while .
in a predicate evaluates to the string concatenation of all text nodes. Again, you can test this claim with the path expression //a[.='Ask Questionmore text']
which will successfully return the a
element.
最后,请记住,某些 XPath 函数只能将一个字符串作为输入.正如 LarsH 在评论中指出的那样,如果这样的 XPath 函数(例如 contains()
)被赋予一个节点序列,它只会处理 first 节点并静默忽略其他.
Finally, keep in mind that some XPath functions can only take one single string as an input. As LarsH has pointed out in the comments, if such an XPath function (e.g. contains()
) is given a sequence of nodes, it will only process the first node and silently ignore the rest.
这篇关于XPath:点和文本()之间的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!