我如何使用类似于下面示例的内容,但结果相反,即文本中不包含(default)
的项目。
<test>
<item>Some text (default)</item>
<item>Some more text</item>
<item>Even more text</item>
</test>
鉴于此
//test/item[contains(text(), '(default)')]
将返回第一个项目。我可以使用not运算符包含吗?
答案 0 :(得分:18)
是的,有:
//test/item[not(contains(text(), '(default)'))]
提示:not()
是XPath中的一个函数,而不是运算符。
另一种可能更好的表达方式是:
//test/item[not(text()[contains(., '(default)')])]
两个表达式之间存在微妙但重要的区别(我们分别称它们为A和B)。
简单案例:如果所有<item>
只有一个文本节点子节点,则A和B的行为相同。
复杂案例:如果<item>
可以包含多个文本节点子节点,则表达式A仅在第一个节点出现'(default)'
时匹配。
这是因为text()
匹配所有文本节点子节点并生成节点集。到目前为止并不奇怪。现在,contains()
接受一个节点集作为它的第一个参数,但它需要将它转换为字符串才能完成它的工作。从node-set到string的转换只生成集合中第一个节点的字符串值,忽略所有其他节点(尝试string(//item)
看看我的意思)。在简单的情况下,这恰好也会发生,但结果并不令人惊讶。
表达式B通过单独显式检查每个文本节点而不是仅检查整个<item>
元素的字符串值来处理此问题。因此,这两者中更加强大。