web-dev-qa-db-ja.com

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>
_
61
Martin Bring

たぶん*[local-name() = 'A' and not(descendant::*[local-name() = 'B'])]

また、ルート要素は1つだけである必要があるため、_/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" />
_
45
alamar

"/A[not(.//B)]"または"/A[not(./B)]"を試してください。

14
Serhiy

最初の/は、XPathをドキュメントのルートから開始しますが、それが意図したとおりではないでしょう。

おそらく、// A [not(B)]を意味します。これは、直接Bの子を持たない任意のレベルでドキュメント内のすべてのAノードを検索します。

または、すでにAノードを含むノードにいる場合は、A [not(B)]をXPathとして使用するだけです。

10
AnthonyWJones

ルートからAを階層のどこかに取得しようとしている場合、これは機能します(xsltで使用される場合は2.0と同様にxslt 1.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を使用する人はいないと確信しています)、大文字と小文字が一致することを確認してください。

3
Rashmi Pandit

これを使って:

/*[local-name()='A' and not(descendant::*[local-name()='B'])]
2
Cobaia