XML文档:
<Home>
<Addr>
<Street>ABC</Street>
<Number>5</Number>
<Comment>BLAH BLAH BLAH <br/><br/>ABC</Comment>
</Addr>
</Home>
XPath表达式:
/
//*
匹配根节点之外的任何后代元素。
[...]
是一个谓词, 它过滤节点集合。它返回true
的节点:
谓词将节点集合过滤[...]以产生新的节点集合。对于要过滤的节点集中的每个节点,都会评估PredicateExpr[...];如果PredicateExpr对该节点求值为true,则该节点包含在新的节点集合中;否则,它不包含。
contains('haystack', 'needle')
如果haystack
包含needle
,则返回true
:
函数:boolean contains(string, string)
如果第一个参数字符串包含第二个参数字符串,则contains函数返回true;否则返回false。
但是
contains()
函数的第一个参数需要传入一个字符串。而且它接受节点作为参数。为了处理这种情况,每个作为第一个参数传递的节点或节点集都会通过
string()
函数
转换为一个字符串:
如果一个参数被调用字符串函数,则该参数将被转换为字符串类型。
string()
函数返回
第一个节点的
string-value
:
通过返回节点集中按文档顺序排列的第一个节点的字符串值来将节点集转换为字符串。如果节点集为空,则返回空字符串。
元素节点的
string-value
:
元素节点的字符串值是元素节点所有后代文本节点的字符串值按文档顺序连接而成的。
文本节点的
string-value
:
文本节点的字符串值是字符数据。
因此,基本上
string-value
是包含在节点中的所有文本(所有后代文本节点的连接)。
text()
是一个节点测试,用于匹配任何文本节点:
节点测试text()
适用于任何文本节点。例如,child::text()将选择上下文节点的文本节点子项。
说到这一点,//*[contains(text(),'ABC')]
匹配包含ABC
的第一个文本节点的任何元素(但不包括根节点)。由于text()
返回包含上下文节点的所有子文本节点的节点集(相对于表达式评估的位置),但contains()
只使用第一个节点。因此,对于上面的文档,该路径匹配Street
元素。
以下表达式//*[text()[contains(.,'ABC')]]
匹配至少有一个包含ABC
的子文本节点的任何元素(但不包括根节点)。.
表示上下文节点。在这种情况下,它是除根节点之外任何元素的子文本节点。因此,对于上面的文档,该路径匹配Street
和Comment
元素。
现在,//*[contains(., 'ABC')]
匹配任何包含 ABC
(在后代文本节点的连接中)的元素(但不包括根节点)。对于上面的文档,它匹配Home
,Addr
,Street
和Comment
元素。因此,//*[contains(., 'BLAH ABC')]
匹配Home
,Addr
和Comment
元素。
//*[contains(text(),'ABC')]
只返回<Street>
元素。它不返回任何<Street>
或<Comment>
的祖先元素。 - Ken Bloom