我有这样的结构:
<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']
但是我怎样才能避免第三种情况,即该属性在其他地方呢?
答案 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])]