2011-01-19 24 views
12

que estoy tratando de encontrar una manera de buscar una cadena dentro de los nodos, pero con exclusión de ythe contenido de algunos subelementos de esos nodos. Claro y simple, quiero buscar una cadena en los párrafos de un texto, excluyendo las notas al pie que son elementos secundarios de los párrafos.XPath/XQuery: buscar texto en un nodo, pero ignorando el contenido de los elementos descendientes específicos

Por ejemplo,

Mi documento bienestar:

<document> 
    <p n="1">My text starts here/</p> 
    <p n="2">Then it goes on there<footnote>It's not a very long text!</footnote></p> 
</document> 

Cuando estoy en busca de "texto", me gustaría que el Xpath/XQuery para recuperar el primer elemento p, pero no el segundo (donde "texto" está contenido solo en el subelemento de la nota al pie).

me han tratado la función , pero recupera los dos elementos p.

Cualquier ayuda sería muy apreciada :)

+0

Buena pregunta, 1. Vea mi respuesta para una breve y fácil expresión XPath 1.0 que selecciona los nodos de texto deseados, incluso en documentos XML mucho más complejos. :) –

Respuesta

14

Quiero buscar una cadena en párrafos de un texto, con exclusión de los notas al pie que son elementos secundarios de los párrafos

un XPath 1.0 - única solución:

Uso:

//p//text()[not(ancestor::footnote) and contains(.,'text')] 

Contra el siguiente documento XML (obtenido de la suya, pero añade p s dentro de un footnote para hacer esto más interesante):

<document> 
    <p n="1">My text starts here/</p> 
    <p n="2">Then it goes on there 
     <footnote>It's not a very long text! 
      <p>text</p> 
     </footnote> 
    </p> 
</document> 

esta expresión XPath selecciona exactamente el nodo de texto deseado:

My text starts here/ 
+0

gracias Dimitre! – Hemka

+0

@Hemka: De nada :) –

+2

+1 Buena respuesta XPath 1.0. –

1

/document/p[text()[contains(., 'text')]] debe hacer.

+0

Gracias Martin! El único problema con este, es que selecciona 'texto' en p, ignorando el contenido de * todos * subelementos. Solo quiero ignorar los elementos de la nota al pie. – Hemka

+0

¿Puede actualizar su pregunta con una muestra de XML más representativa para que quede más claro cuáles son los requisitos? Does '/ document/p [descenddant-or-self :: * [not (self :: footnote)]/text() [contains (., 'Text')]]' ¿es suficiente? –

4
//p[(.//text() except .//footnote//text())[contains(., 'text')]] 
+1

+1 Buena respuesta de XPath 2.0. –

0

Para el registro, como complemento a las otras respuestas, he encontrado esta solución que también parece hacer el trabajo:

//p[contains(child::text()|not(descendant::footnote), "text")] 
+1

Esta no es una expresión XPath válida. El operador de unión ('|') requiere que ambos operandos sean nodos, pero el tipo de retorno de la función 'not()' es xs: booleano: cualquier motor XPath compatible * debe * generar un error. –

+0

Ouch, tienes razón Dimitre, Oxygen provocó un error.¡Extraño, la expresión funcionó en mi script PHP! – Hemka

Cuestiones relacionadas