我的问题是关于使用dot和text()in的细节XPath。例如,以下几find_element行返回相同的元素:
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()什么?
.
.和之间存在差异text(),但是由于您输入的文档,这种差异可能不会浮出水面。
如果您的输入文档看起来像(给定您的XPath表达式可以想象的最简单的文档)
例子1
<html> <a>Ask Question</a> </html>
然后//a[text()="Ask Question"]和//a[.="Ask Question"]确实返回完全相同的结果。但是考虑一个看起来像下面的输入文档
//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"]什么都不返回!
a
other
这是因为两个谓词([和之间的所有内容])的含义都不同。[text()="Ask Question"]实际的意思是:如果元素的任何文本节点都包含恰好包含“问问题”的文本,则返回true。另一方面,[.="Ask Question"]意味着:如果元素的 字符串值 与“问问题”相同,则返回true 。
[
]
[text()="Ask Question"]
[.="Ask Question"]
在XPath模型中,如果其他元素干扰文本,则可以将XML元素内的 文本 划分为多个 文本节点 ,如上面的 示例2 所示。在那里,该other元素介于“问问题”和换行符之间,换行符也视为文本内容。
为了使示例更清晰,请考虑将其作为输入文档:
例子3
<a>Ask Question<other/>more text</a>
在此,a元素实际上包含 两个 文本节点“问问题”和“更多文本”,因为它们都是的直接子代a。您可以通过//a/text()在此文档上运行进行测试,该文档会返回(单个结果以分隔----):
//a/text()
----
Ask Question ----------------------- more text
因此,在这种情况下,text()将返回一组单独的节点,同时.在谓词中评估所有文本节点的字符串连接。同样,您可以使用路径表达式测试此声明,该表达式//a[.='Ask Questionmore text']将成功返回a元素。
//a[.='Ask Questionmore text']
最后,请记住,某些XPath函数只能将一个字符串作为输入。正如LarsH在评论中指出的那样,如果给这样的XPath函数(例如contains())指定了一系列节点,它将仅处理第 一个 节点,而忽略其余节点。
contains()