我的问题是关于在 XPath
中使用点和 text()
的细节。例如,以下 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"]
确实返回完全相同的结果。但是考虑一个不同的输入文档,看起来像
示例 2
<html>
<a>Ask Question<other/>
</a>
</html>
其中 a
元素还有一个紧跟在“提问”之后的子元素 other
。给定第二个输入文档,//a[text()="Ask Question"]
仍然返回 a
元素,而 //a[.="Ask Question"]
不返回任何内容!
这是因为两个谓词([
和 ]
之间的所有内容)的含义不同。 [text()="Ask Question"]
实际上意味着:如果元素的任何文本节点恰好包含文本“Ask Question”,则返回 true。另一方面,[.="Ask Question"]
表示:如果元素的 字符串值 与“Ask Question”相同,则返回 true。
在 XPath 模型中,如果其他元素干扰文本,XML 元素中的文本可以划分为多个 文本节点,如上面的示例 2。在那里,other
元素位于“Ask Question”和也算作文本内容的换行符之间。
为了做一个更清楚的例子,考虑作为一个输入文档:
示例 3
<a>Ask Question<other/>more text</a>
在这里,a
元素实际上包含 两个 文本节点,“Ask Question”和“more text”,因为它们都是 a
的直接子节点。您可以通过在此文档上运行 //a/text()
来测试它,这将返回(由 ----
分隔的各个结果):
Ask Question
-----------------------
more text
因此,在这种情况下,text()
返回一组单独的节点,而谓词中的 .
计算所有文本节点的字符串连接。同样,您可以使用将成功返回 a
元素的路径表达式 //a[.='Ask Questionmore text']
测试此声明。
最后,请记住,某些 XPath 函数只能将一个字符串作为输入。正如 LarsH 在评论中指出的那样,如果给这样的 XPath 函数(例如 contains()
)一个节点序列,它将只处理 first 节点并默默地忽略其余节点。
dot (".")
和 text()
之间有很大区别:-
XPath 中的点(“.”)称为“上下文项表达式”,因为它引用上下文项。这可以与节点(例如元素、属性或文本节点)或原子值(例如字符串、数字或布尔值)匹配。而 text() 指的是仅匹配字符串形式的元素文本。
点 (".") 表示法是 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')]
匹配 :) 无论如何,谢谢你的回答
link
位于 a
的第一个文本节点子节点中时才有效。在 Saurabh 的示例中,<img>
元素之前可能有一个纯空格文本节点,在这种情况下,您的注释中的 XPath 表达式将与锚点不匹配。原因是 contains()
和 normalize-space()
函数采用节点集中 first 节点的字符串值作为它们的第一个参数。
text()
仅选择直到第一个内部元素的文本是不正确的。 text()
选择所有文本节点(上下文节点的子节点,除非您指定不同的轴)。但是,如果您将 text()
选择的节点集传递给 contains()
,就像您所做的那样,则通过获取节点集中 first 节点的字符串值,它将其转换为字符串。 (w3.org/TR/xpath/#function-string)
text()
只选择了 first 文本节点,这完全不正确。
enter image description here XPath text() 函数定位文本节点内的元素,而点 (.) 定位文本节点内或外的元素。 在图像描述屏幕截图中,XPath text() 函数将只在 DOM 示例 2 中定位成功。它在 DOM 示例 1 中不会成功,因为它位于标签之间。
此外,DOM 示例 3 中的 text() 函数不会成功,因为成功与元素没有直接关系。这是一个视频演示,解释了 text() 和 dot (.) 之间的区别https://youtu.be/oi2Q7-0ZIBg
不定期副业成功案例分享