1

我看到一个非常奇怪的行为,当试图限制通过将祖先::* 应用到一个元素给出的结果时,我总是得到一个额外的祖先,尽管被谓词明确排除。

这里的代码:

XML:

<?xml version="1.0" encoding="UTF-8"?>
<root>
  <level_a> 
    <level_b> 
      <level_c> 
        <level_d> 
          <level_e/> 
        </level_d> 
      </level_c> 
    </level_b> 
  </level_a>
  <level_b> 
    <level_c> 
      <level_d> 
        <level_d> 
          <level_e/> 
        </level_d> 
      </level_d> 
    </level_c> 
  </level_b>
</root>

XPath:

(//level_d[not(level_d)])[last()]/ancestor::*[level_c|level_b] 

所以基本上我选择了没有嵌套另一个level_d元素的level_d元素,获取最后一个元素并尝试让所有祖先元素达到元素level_b。但是我使用 Altova XMLSpy 2011 看到的结果是:

  • level_a
  • level_b

我不太明白为什么我会得到这个结果,以及如何改进我的 xpath 以有效地将祖先限制到level_b(即 level_c 和 level_b)。

非常感谢任何提示!
问候
Vlax

4

2 回答 2

2

Wellancestor::*[level_c|level_b]选择祖先轴上所有具有 alevel_clevel_b子元素的元素。

你可能想要(//level_d[not(level_d)])[last()]/ancestor::*[self::level_c|self::level_b].

或者使用您想要的文字描述“有效地将祖先限制在 level_b” (//level_d[not(level_d)])[last()]/ancestor::level_b

于 2013-06-04T15:59:08.580 回答
2

我认为您得到了正确的结果,因为ancestor::*[level_c|level_b]我将子句读作“包含元素 level_b 或 level_c 的所有祖先”。所以,level_b 可以,因为它包含 level_c,level_a 也可以,因为它包含 level_b。

因此,如果我将您的 XPath 更改为(//level_d[not(level_d)])[last()]/ancestor::*[level_c]它只会导致 level_b 。

可能这不是您所要求的,但我不确定我是否理解您的 XPath 的目的:-)

于 2013-06-04T16:04:00.590 回答