2009-09-10 10 views
19

Może ktoś proszę sugerować format wyrażenie XPath, która zwraca ciąg znaków zawierający konkatenowanych wartości niektórych węzłów kwalifikacyjna dzieckiem elementu, ale ignorując inne:XPath aby powrócić ciąg konkatenacji węzła kwalifikacyjna dziecięcej wartości

<div> 
    This text node should be returned. 
    <em>And the value of this element.</em> 
    And this. 
    <p>But this paragraph element should be ignored.</p> 
</div> 

Zwrócona wartość powinna być pojedynczym ciągiem znaków:

This text node should be returned. And the value of this element. And this. 

Czy jest to możliwe w pojedynczym wyrażeniu XPath?

Dzięki.

Odpowiedz

16

W XPath 1.0:

Można użyć

/div//text()[not(parent::p)] 

uchwycić WANTED węzły tekstowe. Samo łączenie nie może być wykonane w XPath 1.0, polecam zrobić to w aplikacji hosta.

+3

Dzięki - masz absolutną rację.Właśnie przeczytałem referencję XPath i odkryłem, że wszystkie funkcje łańcuchowe niejawnie działają na pierwszym węźle w zestawie węzłów, więc w konsekwencji nie ma możliwości połączenia selekcji i konkatenacji. –

+1

W Xpath 2.0 robi się to łatwo - zobacz moją odpowiedź :) –

+0

Piękny i elegancki. Dobra na ciebie! – Aaron

5

To spojrzenie, które działa:

Korzystanie jako kontekst /div/:

text() | em/text() 

Albo bez użycia kontekstu:

/div/text() | /div/em/text() 

Jeśli chcesz Concat pierwsze dwa sznurki, użytkowania to:

concat(/div/text(), /div/em/text()) 
+1

Dzięki. To dobry krok we właściwym kierunku. Ale nie widzę sposobu na połączenie wyników. Kiedy zawijam to w wywołaniu funkcji string(), zwraca ona tylko wartość pierwszego wybranego węzła. –

+0

Tak, i, jak można zobaczyć, moje rozwiązanie działa tak samo jak "poprawne" rozwiązanie. ¬ Możesz dołączyć (...) węzły, ale nie zobaczysz trzeciego "tekstu". Spróbuj tego: concat (/ div/text(),/div/em/text()) – eLZahR

6
/div//text() 

podwójne siły slash wyodrębnić tekst niezależnie od węzłów pośrednich

+0

Jest to trochę związane i przydatne wiedzieć. Dzięki. – Aaron

+0

@Aaron, zapraszam. – Dewfy

26

W XPath 2.0:

string-join(/*/node()[not(self::p)], '')

+10

+1 Tradycyjnie pozostawiam wam odpowiedzi XPath 2.0. ;-) – Tomalak

+0

Ale funkcja zagnieżdżona nie jest obsługiwana w string-join() jak string-join (normalize-space (// a [@ class = "title"] // text())) – SIslam

+0

@SIslam, To nie jest problem "zagnieżdżonej funkcji", ale tylko, że 'normalize-space()' przyjmuje pojedynczy argument - a nie sekwencję. Możesz użyć tego wyrażenia zamiast: 'string-join (// a [@ class = 'title']/normalize-space())'. Oczywiście musisz dodać drugi argument do wywołania 'string-join()' –

-2

można użyć dla-każdej pętli, jak również i montujemy wartości w zmiennej jak ten

<xsl:variable name="newstring"> 
    <xsl:for-each select="/div//text()"> 
     <xsl:value-of select="."/> 
    </xsl:for-each> 
    </xsl:variable> 
+1

Nie dotyczy. Plakat zapytał o XQuery. – Alberto

0

Jeśli chcesz wszystkie dzieci z wyjątkiem p, możesz wypróbować następujące ...

string-join(//*[name() != 'p']/text(), "") 

która zwraca ...

This text node should be returned. 
And the value of this element. 
And this. 
Powiązane problemy