XPath: выбрать текстовый узел

150

Имея следующий XML:

<node>Text1<subnode/>text2</node>

Как выбрать первый или второй текстовый узел через XPath?

Что-то вроде этого:

/node/text()[2]

конечно, не работает, потому что это объединенный результат каждого текста внутри узла.

ядро
источник
11
Вы писали: /node/text()[2][...] не работает, потому что это объединенный результат каждого текста внутри узла. Это неправильно: это означает, что второй текстовый узел - дочерний nodeэлемент корневого элемента . Значение строки (конкатенация текстовых узлов - потомков) будетstring(/node)
Вы имеете в виду, что запрос Xpath должен работать? Ну, я думаю, у меня есть еще одна проблема тогда. ;) Спасибо!
ядро
Хороший вопрос, +1. См. Мой ответ для объяснения и несколько выражений XPath, которые выбирают либо весь, либо определенный дочерний элемент текстового узла верхнего элемента.
Димитр Новатчев

Ответы:

183

Имея следующий XML:

<node>Text1<subnode/>text2</node> 

Как выбрать первый или второй текстовый узел через XPath?

Используйте :

/node/text()

При этом выбираются все дочерние элементы текстового узла верхнего элемента (с именем «узел») документа XML.

/node/text()[1]

При этом выбирается первый дочерний элемент текстового узла верхнего элемента (с именем «узел») документа XML.

/node/text()[2]

При этом выбирается второй дочерний элемент текстового узла верхнего элемента (с именем «узел») документа XML.

/node/text()[someInteger]

Это выбирает someInteger-й дочерний элемент текстового узла верхнего элемента (названного "узлом") документа XML. Это эквивалентно следующему выражению XPath:

/node/text()[position() = someInteger]
Димитр Новатчев
источник
@NaftuliTzviKay: это означает, что Chrome не работает. /node[2]не должен выбирать какой-либо узел, если исходный XML-документ правильно сформирован. По определению в правильно сформированном XML-документе есть только один (один) верхний элемент - также известный какdocument-element
Dimitre Novatchev 27.02.15
1
Это работает в PHP? Я пытаюсь перебрать только текстовые узлы, даже те, которые находятся между наборами тегов. Проблема заключается в том, что содержимое нескольких текстовых узлов разбивается вместе, независимо от тегов. В //*[text()]любом случае /html/text()не работает.
Аарон Джиллион
2
@AaronGillion, да, AFAIK PHP имеет правильно работающую оценку XPath 1.0. Обратите внимание, что /html/text()не выделяются все текстовые узлы в документе - только текстовые узлы, которые являются дочерними (не потомками) верхнего htmlэлемента. Вы, вероятно, хотите /html//text() . Для построения выражений XPath обычно требуется некоторое знание и понимание XPath.
Димитр Новатчев
Спасибо. Я понял трюк с двойной косой чертой немного назад!
Аарон Гиллион,
@AaronGillion, пожалуйста. Вы можете изучить основы XPath 1.0 и 2.0 в модуле 2 этого онлайн-курса обучения: pluralsight.com/courses/xslt-foundations-part1
Dimitre Novatchev
29

ваш xpath должен работать. Я проверил ваш xpath и мой в реализации MarkLogic и Zorba Xquery / Xpath.

Оба должны работать.

/node/child::text()[1] - should return Text1
/node/child::text()[2] - should return text2


/node/text()[1] - should return Text1
/node/text()[2] - should return text2
kadalamittai
источник