XSLT 2.0:将祖先轴限制在文档树的某个元素级别

时间:2013-06-04 15:48:03

标签: xslt xpath xslt-2.0 xpath-2.0

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

这里是代码:

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)。

非常感谢任何提示! 问候
明经

2 个答案:

答案 0 :(得分:2)

ancestor::*[level_c|level_b]选择祖先轴上具有level_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

答案 1 :(得分: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的目的: - )