XPath - 获取没有特定类型子节点的节点

时间:2009-05-14 08:39:44

标签: xpath

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>

5 个答案:

答案 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'])]