用于选择所有包含属性的祖先的所有节点的XPath表达式

时间:2014-10-21 14:00:08

标签: xpath

我有这样的结构:

<root>
<n1 a='1'>
    <n2 a='1'>
        <n3 a='1'> - correct
        </n3>
    </n2>
</n1>

<n1 a='1'>
    <n2 a='1'>
        <n3 a='0'> - false
        </n3>
    </n2>
</n1>

<n1 a='0'>
    <n2 a='1'>
        <n3 a='1'> - false
        </n3>
    </n2>
</n1>

<n1 a='1'>
    <n2 a='0'>
        <n3 a='1'> - false
        </n3>
    </n2>
</n1>
</root>

但深度可变。

我遇到的问题是只获取第一个示例 - 每个预先包含属性a = 1的节点

很容易解决第二个例子:

.//*[@a='1']

但是我怎样才能避免第三种情况,即该属性在其他地方呢?

1 个答案:

答案 0 :(得分:2)

以下内容应该有效:

//n1[not(n1) and not(ancestor-or-self::n1[@a=0])]

这意味着:节点本身是一个叶子(没有n1个孩子),它没有a=0的祖先(包括它自己)。

为了测试,我使用了以下XML:

<r>
<n1 a='1'>
  <n1 a='1'>
    <n1 a='1'>yes</n1>
  </n1>
</n1>
<n1 a='1'>
  <n1 a='1'>
    <n1 a='0'>no 1</n1>
  </n1>
</n1>
<n1 a='0'>
  <n1 a='1'>
    <n1 a='1'>no 2</n1>
  </n1>
</n1>
</r>

以及以下xsh脚本:

open file.xml ;
echo //n1[not(n1) and not(ancestor-or-self::n1[@a=0])] ;

输出:yes

更新

对于您问题中的新XML,只需在查询中将n1替换为*

//*[not(*) and not(ancestor-or-self::*[@a=0])]