一尘不染

XPath:dot和text()之间的区别

selenium

我的问题是关于使用dot和text()in的细节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()什么?


阅读 266

收藏
2020-06-26

共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"]实际的意思是:如果元素的任何文本节点都包含恰好包含“问问题”的文本,则返回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())指定了一系列节点,它将仅处理第
一个 节点,而忽略其余节点。

2020-06-26