2009-09-10 4 views
19

Может кто-нибудь пожалуйста, предложить формат выражения XPath, который возвращает строку, содержащую связанные значения определенных квалификационные дочерних узлов элемента, но игнорирующие другие:XPath вернуть конкатенацию квалифицируемых дочернего узла значение

<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> 

Возвращаемое значение должно быть одной строкой:

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

Возможно ли это в одном выражении XPath?

Спасибо.

ответ

16

В XPath 1.0:

Вы можете использовать

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

для захвата разыскиваемых текстовых узлов. Сама конкатенация не может быть выполнена в XPath 1.0, я рекомендую сделать это в главном приложении.

+3

Спасибо - вы абсолютно прав.Я просто прочитал ссылку XPath и обнаружил, что все строковые функции неявно работают на первом узле в наборе узлов, поэтому нет возможности комбинировать выбор и конкатенацию. –

+1

В Xpath 2.0 это делается легко - см. Мой ответ :) –

+0

Lovely and elegant. Хорошо на вас! – Aaron

5

Этот вид, что работает:

Использование в качестве контекста /div/:

text() | em/text() 

Или без использования контекста:

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

Если вы хотите Concat первые две строки, используйте это:

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

Спасибо. Это хороший шаг в правильном направлении. Но я не вижу, как конкатенировать результаты. Когда я обертываю это при вызове функции string(), он возвращает только значение первого выбранного узла. –

+0

Да, и, как вы могли видеть, мое решение делает то же самое, что и «правильное» решение. ¬¬ Вы можете конкат (узлы), но вы не увидите третьего «текста». Попробуйте следующее: concat (/ div/text(),/div/em/text()) – eLZahR

6
/div//text() 

двойной силы слэш для извлечения текста, независимо от промежуточных узлов

+0

Это родственный и удобный для понимания. Благодарю. – Aaron

+0

@Aaron добро пожаловать – Dewfy

26

В XPath 2.0:

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

+10

+1 Традиционно я оставляю ответы XPath 2.0 вам. ;-) – Tomalak

+0

Но вложенная функция не поддерживается в string-join(), как string-join (normalize-space (// a [@ class = "title"] // text())) – SIslam

+0

@SIslam, это не проблема «вложенной функции», но только что 'normalize-space()' принимает единственный аргумент, а не последовательность. Вместо этого вы можете использовать это выражение: 'string-join (// a [@ class = 'title']/normalize-space())'. Конечно, вы должны добавить второй аргумент в вызов 'string-join()' –

-2

Вы могли бы использовать для-каждого цикла, а также и собрать значения в переменной, как этот

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

Не имеет значения. Плакат спросил о XQuery. – Alberto

0

Если вы хотите все дети, кроме п, вы можете попробовать следующее ...

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

который возвращает ...

This text node should be returned. 
And the value of this element. 
And this. 
Смежные вопросы