. 和 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 节点并默默地忽略其余节点。