XML:/A/B
或 /A
我想获取所有没有任何 B
子节点的 A
节点。
我试过了
/A[not(B)]
/A[not(exists(B))]
没有成功
如果可能的话,我更喜欢语法为 /*[local-name()="A" and .... ]
的解决方案。有什么可行的想法吗?
澄清。 xml 看起来像:
<WhatEver>
<A>
<B></B>
</A>
</WhatEver>
或者
<WhatEver>
<A></A>
</WhatEver>
//A[not(B)] or /*/A[not(B)]
?
也许*[local-name() = 'A' and not(descendant::*[local-name() = 'B'])]
?
此外,应该只有一个根元素,因此对于 /A[...]
,您要么获取所有 XML,要么没有。也许是 //A[not(B)]
或 /*/A[not(B)]
?
我真的不明白为什么 /A[not(B)]
不适合你。
~/xml% xmllint ab.xml
<?xml version="1.0"?>
<root>
<A id="1">
<B/>
</A>
<A id="2">
</A>
<A id="3">
<B/>
<B/>
</A>
<A id="4"/>
</root>
~/xml% xpath ab.xml '/root/A[not(B)]'
Found 2 nodes:
-- NODE --
<A id="2">
</A>
-- NODE --
<A id="4" />
试试这个 "/A[not(.//B)]"
或这个 "/A[not(./B)]"
。
第一个 / 导致 XPath 从文档的根目录开始,我怀疑这是您的意图。
也许您的意思是 //A[not(B)] 它将在文档中的任何级别找到所有没有直接 B 子节点的 A 节点。
或者您可能已经在一个包含 A 节点的节点上,在这种情况下您只需要 A[not(B)] 作为 XPath。
如果您试图从根目录中获取层次结构中的 A,则此方法有效(对于 xslt 1.0 和 2.0,以防在 xslt 中使用)
//descendant-or-self::node()[local-name(.) = 'a' and not(count(b))]
或者你也可以这样做
//descendant-or-self::node()[local-name(.) = 'a' and not(b)]
或者也
//descendant-or-self::node()[local-name(.) = 'a' and not(child::b)]
xslt 中没有多种方法可以实现相同的目标。
注意:XPath 区分大小写,因此如果您的节点名称不同(我敢肯定,没有人会使用 A、B),那么请确保大小写匹配。
用这个:
/*[local-name()='A' and not(descendant::*[local-name()='B'])]