XML:/A/B
或/A
我希望获得所有A
个没有B
个孩子的节点。
我试过
/A[not(B)]
/A[not(exists(B))]
没有成功
如果可能的话,我更喜欢使用语法/*[local-name()="A" and .... ]
的解决方案。有效的想法吗?
澄清。 xml看起来像:
<WhatEver>
<A>
<B></B>
</A>
</WhatEver>
或
<WhatEver>
<A></A>
</WhatEver>
答案 0 :(得分:44)
也许
*[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" />
答案 1 :(得分:13)
试试这个"/A[not(.//B)]"
或此"/A[not(./B)]"
。
答案 2 :(得分:10)
第一个/导致XPath从文档的根开始,我怀疑这是你的意图。
也许你的意思是// [不是(B)]会在任何级别找到文档中没有直接B子项的所有A节点。
或者您可能已经在包含A节点的节点上,在这种情况下,您只需要A [not(B)]作为XPath。
答案 3 :(得分:3)
如果您尝试从根目录中获取A层次结构中的任何位置,则可以使用(对于xslt 1.0以及在xslt中使用的情况下为2.0)
//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),那么请确保案例匹配。
答案 4 :(得分:2)
使用此:
/*[local-name()='A' and not(descendant::*[local-name()='B'])]