web-dev-qa-db-de.com

XPath - Knoten ohne untergeordnetes Element eines bestimmten Typs abrufen

XML: /A/B Oder /A

Ich möchte alle A Knoten erhalten, die keine B Kinder haben.

Ich habe es versucht

/A[not(B)]  
/A[not(exists(B))]

ohne Erfolg

Ich bevorzuge eine Lösung mit der Syntax /*[local-name()="A" and .... ], wenn möglich. Irgendwelche Ideen, die funktionieren?

Klärung. Die xml sieht so aus:

<WhatEver>
  <A>
    <B></B>
  </A>
</WhatEver> 

oder

<WhatEver>
  <A></A>
</WhatEver>
61
Martin Bring

Vielleicht *[local-name() = 'A' and not(descendant::*[local-name() = 'B'])]?

Außerdem sollte es nur ein Root-Element geben, sodass Sie für /A[...] Entweder Ihre gesamte XML-Datei zurückerhalten oder keine. Vielleicht //A[not(B)] oder /*/A[not(B)]?

Ich verstehe nicht wirklich, warum /A[not(B)] bei Ihnen nicht funktioniert.

~/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

Versuchen Sie dieses "/A[not(.//B)]" oder dieses "/A[not(./B)]".

14
Serhiy

Das erste/bewirkt, dass XPath im Stammverzeichnis des Dokuments beginnt. Ich bezweifle, dass Sie dies beabsichtigt haben.

Vielleicht meinten Sie // A [nicht (B)], das alle A-Knoten im Dokument auf jeder Ebene finden würde, die kein direktes B-Kind haben.

Oder Sie befinden sich bereits an einem Knoten, der A-Knoten enthält. In diesem Fall möchten Sie nur A [nicht (B)] als XPath.

10
AnthonyWJones

Wenn Sie versuchen, A irgendwo in der Hierarchie von der Wurzel zu bekommen, funktioniert dies (für xslt 1.0 und 2.0, falls es in xslt verwendet wird).

//descendant-or-self::node()[local-name(.) = 'a' and not(count(b))]

ODER Sie können auch tun

//descendant-or-self::node()[local-name(.) = 'a' and not(b)]

ODER auch

//descendant-or-self::node()[local-name(.) = 'a' and not(child::b)]

Es gibt in xslt keine Möglichkeit, dasselbe zu erreichen.

Hinweis: Bei XPaths wird zwischen Groß- und Kleinschreibung unterschieden. Wenn Ihre Knotennamen also unterschiedlich sind (ich bin sicher, dass niemand A, B verwenden wird), stellen Sie bitte sicher, dass die Groß- und Kleinschreibung übereinstimmt.

3
Rashmi Pandit

Benutze das:

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