XPath: wybierz węzeł tekstowy

150

Mając następujący XML:

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

Jak wybrać pierwszy lub drugi węzeł tekstowy za pośrednictwem XPath?

Coś takiego:

/node/text()[2]

oczywiście nie działa, ponieważ jest to scalony wynik każdego tekstu wewnątrz węzła.

jądro
źródło
11
Napisałeś: /node/text()[2][...] nie działa, ponieważ jest to scalony wynik każdego tekstu wewnątrz węzła . Źle: oznacza to, że drugi węzeł tekstowy jest dzieckiem nodeelementu głównego . Wartość ciągu (konkatenacja string(/node)
Masz na myśli, że zapytanie Xpath powinno działać? Cóż, myślę, że mam inny problem gdzieś indziej. ;) Dzięki!
kernel
Dobre pytanie, +1. Zobacz moją odpowiedź dla wyjaśnienia i kilka wyrażeń XPath, które wybierają całość lub określony element potomny węzła tekstowego górnego elementu.
Dimitre Novatchev

Odpowiedzi:

183

Mając następujący XML:

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

Jak wybrać pierwszy lub drugi węzeł tekstowy za pośrednictwem XPath?

Zastosowanie :

/node/text()

Powoduje to zaznaczenie wszystkich elementów potomnych węzła tekstowego najwyższego elementu (o nazwie „węzeł”) dokumentu XML.

/node/text()[1]

Powoduje to zaznaczenie pierwszego elementu podrzędnego węzła tekstowego najwyższego elementu (o nazwie „węzeł”) dokumentu XML.

/node/text()[2]

Spowoduje to wybranie drugiego podrzędnego węzła tekstowego najwyższego elementu (zwanego „węzłem”) dokumentu XML.

/node/text()[someInteger]

Spowoduje to wybranie someInteger-th węzła tekstowego elementu podrzędnego najwyższego elementu (o nazwie „węzeł”) dokumentu XML. Jest równoważne z następującym wyrażeniem XPath:

/node/text()[position() = someInteger]
Dimitre Novatchev
źródło
@NaftuliTzviKay: To oznacza, że ​​Chrome jest uszkodzony. /node[2]nie może wybierać żadnego węzła, jeśli źródłowy dokument XML jest poprawnie sformułowany. Z definicji w dobrze sformułowanym dokumencie XML jest tylko jeden (pojedynczy) górny element - znany również jakodocument-element
Dimitre Novatchev.
1
Czy to działa w PHP? Próbuję przeglądać tylko węzły tekstowe, nawet te znajdujące się między zestawem tagów. Problem polega na tym, że niszczy ze sobą zawartość wielu węzłów tekstowych, niezależnie od tagów. Korzystanie //*[text()]mimo wszystko. /html/text()nie działa.
Aaron Gillion
2
@AaronGillion, Tak, AFAIK PHP ma poprawnie działającą ocenę XPath 1.0. Zwróć uwagę, że /html/text()nie zaznacza wszystkich węzłów tekstowych w dokumencie - tylko węzły tekstowe, które są dziećmi (nie potomkami) górnego htmlelementu. Prawdopodobnie chcesz /html//text() . Do konstruowania wyrażeń XPath jest zwykle wymagana pewna znajomość i zrozumienie języka XPath.
Dimitre Novatchev
Dzięki. Jakiś czas temu wymyśliłem sztuczkę z podwójnym cięciem!
Aaron Gillion
@AaronGillion, nie ma za co. Możesz nauczyć się podstaw XPath 1.0 i 2.0 w module 2 tego szkolenia online: pluralsight.com/courses/xslt-foundations-part1
Dimitre Novatchev
29

twoja ścieżka xpath powinna działać. Przetestowałem twoją i moją xpath w implementacji MarkLogic i Zorba Xquery / Xpath.

Obie powinny działać.

/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
źródło