2009-09-10 16 views
19

Puede alguien por favor sugerir un formato de expresión XPath que devuelve un valor de cadena que contiene los valores concatenados de ciertos hijo calificado nodos de un elemento, pero haciendo caso omiso de los demás:XPath para devolver la concatenación de cadenas de nodo hijo calificado valores

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

El valor devuelto debe ser una sola cadena:

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

¿Es esto posible en una sola expresión XPath?

Gracias.

Respuesta

16

En XPath 1.0:

Puede utilizar

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

para capturar los nodos de texto deseados. La concatenación en sí no se puede hacer en XPath 1.0, recomiendo hacerlo en la aplicación host.

+3

Gracias - estás absolutamente en lo correcto.Acabo de leer la referencia de XPath y descubrí que todas las funciones de cadena funcionan implícitamente en el primer nodo en un conjunto de nodos, por lo que no hay forma de combinar la selección y la concatenación. –

+1

En Xpath 2.0 esto se hace fácilmente - vea mi respuesta :) –

+0

Encantador y elegante. ¡Bien en ti! – Aaron

5

Esta mirada que trabaja:

Utilizando como marco /div/:

text() | em/text() 

o sin el uso del contexto:

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

Si desea concat las dos primeras cuerdas, uso esto:

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

Gracias. Este es un buen paso en la dirección correcta. Pero no puedo ver cómo concatenar los resultados. Cuando envuelvo esto en una llamada a la función de cadena(), solo devuelve el valor del primer nodo seleccionado. –

+0

Sí, y, como puede ver, mi solución hace lo mismo que la solución "correcta". ¬¬ Puede concat (...) nodos, pero, no verá el tercer "texto". Pruebe esto: concat (/ div/text(),/div/em/text()) – eLZahR

6
/div//text() 

fuerzas dos barras diagonales para extraer el texto independientemente de nodos intermedios

+0

Esto está relacionado y es útil saberlo. Gracias. – Aaron

+0

@ Aaron eres bienvenido – Dewfy

26

En XPath 2.0:

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

+10

+1 Tradicionalmente, dejo las respuestas de XPath 2.0 para usted. ;-) – Tomalak

+0

Pero la función anidada no se admite en string-join() como string-join (normalize-space (// a [@ class = "title"] // text())) – SIslam

+0

@SIslam, no es un problema de "función anidada", pero solo que 'normalize-space()' toma un solo argumento, no una secuencia. Puede usar esta expresión en su lugar: 'string-join (// a [@ class = 'title']/normalize-space())'. Por supuesto, debe agregar un segundo argumento a la llamada de 'string-join()' –

-2

Se puede usar un, así como para-cada bucle y ensamblar los valores de una variable como esto

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

No relevante. Poster preguntó por XQuery. – Alberto

0

Si desea todos los niños excepto p, puede intentar lo siguiente ...

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

que devuelve ...

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