2010-10-13 4 views
41

Я считаю, что это возможно, но не смог понять синтаксис. Что-то вроде этого:Как выбрать все листовые узлы с использованием выражения XPath?

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

но это неправильное.

+0

Хороший вопрос, +1. См. Мой ответ для, вероятно, кратчайшего выражения XPath, которое выбирает точно все листовые узлы. :) –

ответ

56

Использование:

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

В случае только элемент листовые узлы хотел (а это требует разъяснения - это элементы, которые имеют не-элементных дети считаются листовые узлы?), То следующий XPath выражение выбирает их:

//*[not(*)] 

Оба выражения выше, вероятно, самый короткий, что выбрать нужный узлы (либо узловые узлы, либо элементы - листовые узлы).

+0

Можете ли вы объяснить, почему это работает? Я просмотрел синтаксис XPath и некоторые уроки, но я не могу понять, почему это работает. – rrs

+0

@rrs: первое выражение выбирает любой узел в документе XML, который не имеет дочерних элементов - это то, что является листовым узлом - по определению. Второй делает что-то подобное, но выбирает любой элемент, у которого нет дочернего элемента. –

+0

Я понимаю, что он делает, но не так, как он это делает. Почему/как 'not (*)' выбирает листовые узлы/элементы? – rrs

1

Почему меньше или равно до 1?

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

сделать тесты и т.д. на этом сайте http://www.whitebeam.org/library/guide/TechNotes/xpathtestbed.rhtm

Довольно полезный ..

+0

Большое спасибо. Это отлично работает. Таким образом, это больше похоже на VB. Я думал, что это должно быть c-style, потому что функции чувствительны к регистру. Почему <= 1? Меня смутил ChildNodes.Count, который возвращает 1 для x, но возвращает 0 для . – newman

+0

и @miliu: проверка счета не требуется. Проверьте ответ @kevpie. – 2010-10-13 19:33:01

+0

@Alejandro, действительно .. –

24

Любые элементы, не имеющие элементов ребенка

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

Большое спасибо. Он отлично работает. – newman

+2

+1 Правильный ответ.Но это означает: * любые элементы без элемента child *. Таким образом, он будет выбирать элементы с дочерним элементом текстового узла, пустые элементы, элементы со смешанным контентом (текстовые узлы, PI, комментарии) – 2010-10-13 19:30:57

+0

+1 @Alejandro, разъяснение оценивается! – kevpie

0

Я добавляю этот ответ XSLT поскольку оно кажется, что передние матчи google не имеют такого решения:

После долгой борьбы с извлекая CDATA в XML, в конечном счете, это выражение работало лучше для меня:

<xsl:template match="*[not(child::*)]/text()"> 
Смежные вопросы