如何在XPath中使用not contains()?

99

我有一些结构如下的XML:

<whatson>
  <productions>    
    <production>
      <category>Film</category>
    </production>
    <production>
      <category>Business</category>
    </production>
    <production>
      <category>Business training</category>
    </production>
  </productions>
</whatson>

我需要选择每个类别中不包含“Business”的产品(因此在此示例中仅为第一个产品)。

XPath是否可以实现这一点?我尝试按照以下方式工作,但没有任何进展:

//production[not(contains(category,'business'))]
4个回答

174

XPath查询区分大小写。看了你的示例(顺便说一句,它很棒,现在没有人再提供例子了!),我只需要将"business"更改为"Business"就可以得到你想要的结果。

//production[not(contains(category,'Business'))]

我已经在Chrome中打开XML文件,并使用开发者工具执行了XPath查询,它只返回了“Film”类别。


谢谢您建议在Chrome中打开XML并使用开发者工具验证XPath是否有效!我正要找一个在线检查器,您的建议简单得多。 - Igor Maximov
你能否只使用//production[not(@category='Business')]而不使用contains吗? - Yi Xiang Chong
@YiXiangChong 如果你不想进行包含搜索,那当然可以,但是原始帖子是在进行包含搜索(因为并非所有元素都明确等于“Business”)。 - Arran

29
我需要选择每个类别中不包含“Business”的产品。
虽然我赞同@Arran的答案是正确的,但我还想补充一点... 严格解释,根据OP的规范会实现为:
//production[category[not(contains(., 'Business'))]]

与其

//production[not(contains(category, 'Business'))]

后者选择每个具有第一个 category 子元素不包含“Business”的生产。当 production 没有 category 子元素或有多个子元素时,这两个 XPath 表达式的行为会有所不同。

只要每个 <production> 恰好只有一个 <category> 子元素,就在实践中没有任何区别,就像你的简短示例 XML 中一样。是否总是可以依赖它是真实的,取决于各种因素,比如是否有强制执行该约束的模式。就个人而言,我会选择更健壮的选项,因为它并没有“成本”... 假设您在问题中陈述的要求确实是正确的(而不是例如“选择每个没有包含“Business”的类别的生产”)。


@LoamyHound:感谢您的纠正!我终于看到了您的答案,并在两年后修复了缺失的括号。 - LarsH

10

您可以使用not(expression)函数。

not()是xpath中的一个函数(而不是运算符)

例如:

//a[not(contains(@id, 'xx'))]

或者

expression != true()

3
应该使用不包含contains()方法的xpath,//production[not(contains(category,'business'))]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接