2010-10-13 18 views
41

Ich glaube, es ist möglich, konnte aber die Syntax nicht herausfinden. Etwas wie dieses:Wie wählt man alle Blattknoten mit XPath Ausdruck aus?

xmlNode.SelectNodes("//*[count(child::*) <= 1]") 

aber das ist nicht korrekt.

+0

Gute Frage, +1. Siehe meine Antwort für den wahrscheinlich kürzesten XPath-Ausdruck, der genau alle Blattknoten auswählt. :) –

Antwort

56

Verwendung:

//node()[not(node())] 

Falls nur Element Blattknoten werden wollte (und dies muss geklärt - sind Elemente, die nicht-Element Kinder als Blattknoten haben?), Dann wird die folgende XPath Ausdruck wählt sie:

//*[not(*)] 

Beide Ausdrücke oben sind wahrscheinlich die kürzeste wählen, dass die gewünschte Knoten (entweder any-node oder element-leaf-Knoten).

+0

Können Sie erklären, warum das funktioniert? Ich habe mir die XPath-Syntax und einige Tutorials angeschaut, aber ich verstehe nicht recht, warum das funktioniert. – rrs

+0

@rrs: Der erste Ausdruck wählt definitionsgemäß einen beliebigen Knoten im XML-Dokument aus, der keine untergeordneten Elemente hat - das ist ein Blattknoten. Die zweite macht etwas ähnliches, wählt aber jedes Element aus, das kein Kindelement hat. –

+0

Ich verstehe, was es tut, aber nicht wie es das tut. Warum/wie wählt 'not (*) Blattknoten/Elemente? – rrs

1

Warum weniger oder gleich-1?

xmlNode.SelectNodes("//*[count(child::*) = 0]")

Make-Tests usw. an dieser Stelle http://www.whitebeam.org/library/guide/TechNotes/xpathtestbed.rhtm

Ziemlich hilfreich ..

+0

Vielen Dank. Das funktioniert großartig. Also, es ist mehr VB Stil gleich. Ich dachte, dass es c-Stil sein sollte, weil Funktionen Groß-und Kleinschreibung beachten. Warum <= 1? Ich wurde von ChildNodes.Count verwirrt, die 1 für x zurückgeben, aber 0 für zurückgibt. – newman

+0

und @miliu: der Count-Test wird nicht benötigt. Überprüfen Sie @kevpie Antwort. –

+0

@ Alejandro, in der Tat .. –

24

Alle Elemente ohne Element Kind

//*[not(child::*)] 
+0

Vielen Dank. Es funktioniert auch super. – newman

+2

+1 Richtige Antwort.Aber es bedeutet: * beliebige Elemente ohne Element Kind *. Also, es wird Elemente mit Textknoten Kind, leere Elemente, Elemente mit gemischtem Inhalt (Textknoten, PI, Kommentare) –

+0

+1 @Alejandro, wird die Klärung geschätzt! – kevpie

0

ich, da es diese XSLT Antwort bin Hinzufügen scheint Google Front-Matches eine solche Lösung zu fehlen:

Nach einem langen Kampf mit CDATA als XML-Extraktion, schließlich arbeitete dieser Ausdruck für mich am besten:

<xsl:template match="*[not(child::*)]/text()"> 
Verwandte Themen