【问题标题】:In XPath, how do you select all nodes not matching a subset?在 XPath 中,如何选择不匹配子集的所有节点?
【发布时间】:2016-08-03 17:11:11
【问题描述】:

我试图在同一级别(其元素名称都不同)获取大量 xml 节点,同时排除某个节点子集。例如:

<root>
  <foo>...</>
  <foo>...</>
  <bar>...</>
  <bar>...</>
  <baz>...</>
  <spam>...</>
  <eggs>...</>
  <toast>...</>
</root>

所以我想要一个 XPath 表达式来给我垃圾邮件鸡蛋和 toast 节点列表,同时排除 foobarbaz 节点。我知道要提前排除的节点,但不知道会留下哪些节点。

【问题讨论】:

    标签: java xml xpath


    【解决方案1】:

    对于格式良好的 XML,

    <root>
      <foo/>
      <foo/>
      <bar/>
      <bar/>
      <baz/>
      <spam/>
      <eggs/>
      <toast/>
    </root>
    

    使用这个 XPath,

    /root/*[not(self::foo or self::bar or self::baz)]
    

    选择所有不在foobarbaz 集合中的root 子元素

    <spam/>
    <eggs/>
    <toast/>
    

    根据要求。

    【讨论】:

      【解决方案2】:

      组合三个 Xpath

      /root/spam | /root/eggs | /root/toast
      

      或者用不同的方式写相同的

      /root/*[contains("spam|eggs|toast", name())]
      

      更新:

      排除一组节点spameggstoast

      /root/*[not(contains("spam|eggs|toast", name()))]
      

      【讨论】:

      • 垃圾邮件、鸡蛋和吐司只是一个例子,在这个级别上可能有成百上千个不同的节点,我只是想排除一个重复很多的小子集
      • 但我可以这样做:/root/*[!contains("foo|bar|baz", name())] 吗?
      • 这个答案不正确;它还将排除spspspa 等元素。可以更正使用字符串相等而不是包含,但我建议using the self:: axis instead.
      • 感谢您的澄清,以上内容确实适用于我当前的测试用例,但我的测试用例现在非常有限。我会想要更明确一点,所以我肯定会同时玩这两个。
      猜你喜欢
      • 2011-06-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-24
      • 1970-01-01
      • 2014-04-08
      • 1970-01-01
      相关资源
      最近更新 更多