【问题标题】:XPath: difference between dot and text()XPath:点和文本()之间的区别
【发布时间】:2016-07-07 08:26:04
【问题描述】:

我的问题是关于在XPath 中使用点和text() 的细节。例如,以下find_element 行返回相同的元素:

driver.get('http://stackoverflow.com/')

driver.find_element_by_xpath('//a[text()=""]')
driver.find_element_by_xpath('//a[.=""]')

那么有什么区别呢?使用.text() 的优缺点是什么?

【问题讨论】:

标签: selenium xpath


【解决方案1】:

.text() 之间存在差异,但由于您的输入文档,这种差异可能不会显现出来。

如果您的输入文档看起来像(给定您的 XPath 表达式可以想象的最简单的文档)

示例 1

<html>
  <a></a>
</html>

然后//a[text()=""]//a[.=""] 确实返回完全相同的结果。但是考虑一个不同的输入文档,看起来像

示例 2

<html>
  <a><other/>
  </a>
</html>

其中a 元素还有一个紧跟在“”之后的子元素other。给定第二个输入文档,//a[text()=""] 仍然返回 a 元素,而 //a[.=""] 不返回任何内容!


这是因为两个谓词([] 之间的所有内容)的含义不同。 [text()=""] 实际上的意思是:如果元素的任何文本节点恰好包含文本“”,则返回 true。另一方面,[.=""] 表示:如果元素的 字符串值 与 "" 相同,则返回 true。

在 XPath 模型中,如果其他元素干扰文本,则 XML 元素中的文本可以划分为多个 文本节点,如上面的示例 2。在那里,other 元素位于 "" 和也算作文本内容的换行符之间。

为了做一个更清楚的例子,将其视为输入文档:

示例 3

<a><other/>more text</a>

这里,a 元素实际上包含 两个 文本节点,“”和“更多文本”,因为它们都是 a 的直接子节点。您可以通过在此文档上运行 //a/text() 来测试它,这将返回(由---- 分隔的各个结果):


-----------------------
more text

因此,在这种情况下,text() 返回一组单独的节点,而谓词中的 . 计算所有文本节点的字符串连接。同样,您可以使用路径表达式 //a[.='more text'] 测试此声明,这将成功返回 a 元素。


最后,请记住,某些 XPath 函数只能将一个字符串作为输入。正如 LarsH 在 cmets 中指出的那样,如果给这样的 XPath 函数(例如 contains())一个节点序列,它将只处理 first 节点并默默地忽略其余节点。

【讨论】:

【解决方案2】:

dot (".")text() 之间有很大的区别:-

  • XPath 中的dot (".") 被称为“上下文项表达式”,因为它引用上下文项。这可以匹配一个节点(例如elementattributetext node)或一个原子值(例如stringnumberboolean)。而text() 指的是仅匹配element text 形式的string

  • dot (".") 表示法是 DOM 中的当前节点。这将是 Node 类型的对象,而使用 XPath 函数 text() 获取元素的文本只会获取到 第一个内部元素的文本。如果您要查找的文本位于 内部元素 之后,则必须使用当前节点而不是 XPath text() 函数来搜索字符串。

举个例子:-

<a href="something.html">
  <img src="filename.gif">
  link
</a>

这里如果你想通过文本link找到锚a元素,你需要使用dot (".")。因为如果您使用//a[contains(.,'link')],它会找到锚点a,但如果您使用//a[contains(text(),'link')]text() 函数似乎找不到它。

希望对你有帮助..:)

【讨论】:

  • 我很确定我可以将锚与//a[contains(text(),'link')] 以及//a[normalize-space(text())='link')] 匹配:) 无论如何,谢谢你的回答
  • @Andersson:你说得很好,但这仅在link 位于a 的第一个文本节点子节点中时才有效。在 Saurabh 的示例中,&lt;img&gt; 元素之前可能有一个纯空格文本节点,在这种情况下,您的注释中的 XPath 表达式将与锚点不匹配。原因是 contains()normalize-space() 函数采用节点集中 first 节点的字符串值作为它们的第一个参数。
  • @SaurabhGaur:你有一些优点,但text() 只选择直到第一个内部元素的文本是不正确的。 text() 选择所有文本节点(上下文节点的子节点,除非您指定不同的轴)。但是,如果您将text() 选择的节点集传递给contains(),就像您所做的那样,则通过获取节点集中 first 节点的字符串值,将其转换为字符串。 (w3.org/TR/xpath/#function-string)
  • 正如@LarsH 正确指出的那样,这个答案的某些部分仍然是错误的,应该修改。答案中最重要的误解是text() 只选择了first 文本节点,这完全不正确。
  • (-1) 这个答案具有误导性。 阅读 LarsH 和 Mathias 的 cmets 以了解如何了解,或者更好地参阅 Mathias's answer 和/ 或 Lars' answer to another question 和/或 my answer to another question 以更好地理解这里的微妙之处。
【解决方案3】:

enter image description here XPath text() 函数定位文本节点内的元素,而点 (.) 定位文本节点内部或外部的元素。 在图像描述屏幕截图中,XPath text() 函数只会定位成功DOM 示例 2。它在 DOM 示例 1 中不会成功,因为它位于标签之间。

另外,DOM 示例 3 中的 text() 函数不会成功,因为成功与元素没有直接关系。这是一个视频演示,解释了 text() 和 dot (.) https://youtu.be/oi2Q7-0ZIBg

之间的区别

【讨论】:

    猜你喜欢
    • 2021-01-08
    • 1970-01-01
    • 2010-10-29
    • 1970-01-01
    • 1970-01-01
    • 2022-11-25
    • 2020-11-22
    • 2011-07-19
    相关资源
    最近更新 更多