2010-10-13 14 views
41

Uważam, że jest to możliwe, ale nie udało mi się ustalić składni. Coś takiego:Jak wybrać wszystkie węzły liści za pomocą wyrażenia XPath?

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

, ale to nie jest poprawne.

+0

dobre pytanie +1. Zobacz moją odpowiedź na prawdopodobnie najkrótsze wyrażenie XPath, które wybiera dokładnie wszystkie węzły liści. :) –

Odpowiedz

56

Zastosowanie:

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

W przypadku tylko elementem liść węzły są chciał (a to wymaga wyjaśnienia - to elementy, które mają dzieci non-element uważane węzły Leaf?), Wtedy po XPath wyrażenie wybiera je:

//*[not(*)] 

Oba wyrażenia powyżej są prawdopodobnie najkrótsza który wybrać żądany węzły (węzły dowolnego węzła lub elementu - liścia).

+0

Czy możesz wyjaśnić, dlaczego to działa? Przejrzałem składnię XPath i kilka samouczków, ale nie mogę do końca zrozumieć, dlaczego to działa. – rrs

+0

@rrs: Pierwsze wyrażenie wybiera dowolny węzeł w dokumencie XML, który nie ma żadnych potomków - z definicji jest to węzeł liścia. Drugi robi coś podobnego, ale wybiera dowolny element, który nie ma elementu child - element. –

+0

Rozumiem, co robi, ale nie jak to robi. Dlaczego/w jaki sposób 'not (*)' wybieram węzły/elementy liści? – rrs

1

Dlaczego mniej lub równa do 1?

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

Dodać badań ETC w tym miejscu http://www.whitebeam.org/library/guide/TechNotes/xpathtestbed.rhtm

bardzo pomocny ..

+0

Dziękuję bardzo. Działa to świetnie. Tak, to jest bardziej równy styl VB. Myślałem, że powinien być w stylu c, ponieważ w funkcjach rozróżniana jest wielkość liter. Dlaczego <= 1? Byłem zdezorientowany przez ChildNodes.Count, który zwraca 1 dla x, ale zwraca 0 dla . – newman

+0

i @miliu: test zliczania nie jest potrzebny. Sprawdź odpowiedź @kevpie. –

+0

@Alejandro, rzeczywiście .. –

24

żadnych elementów bez elementu podrzędnego

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

Dziękuję bardzo. Działa również świetnie. – newman

+2

+1 Prawidłowa odpowiedź.Ale oznacza to: * dowolne elementy bez elementu child *. Dlatego wybierze elementy z węzłem tekstowym, pustymi elementami, elementami o mieszanej zawartości (węzły tekstowe, PI, komentarze). –

+0

+1 @Alejandro, zrozumienie jest mile widziane! – kevpie

0

Dodaję ten XSLT odpowiedź od niego Wygląda na to, że w początkowych meczach google brakuje takiego rozwiązania:

Po długiej walce z wydobycia CDATA jako XML, ostatecznie, to wyrażenie pracował dla mnie najlepsze:

<xsl:template match="*[not(child::*)]/text()"> 
Powiązane problemy