2010-09-07 14 views
168

Tengo un pequeño problema con XPath contiene con dom4j ...XPath contiene (texto(), 'un trozo de cuerda') no funciona cuando se utiliza con nodo con más de un texto subnodo

digamos que mi XML es

<Home> 
    <Addr> 
     <Street>ABC</Street> 
     <Number>5</Number> 
     <Comment>BLAH BLAH BLAH <br/><br/>ABC</Comment> 
    </Addr> 
</Home> 

Digamos que quiero encontrar todos los nodos que tienen ABC en el texto dado el elemento raíz ...

Así que el XPath que iba necesaria para escribir habría

//*[contains(text(),'ABC')]

Sin embargo, esto no es lo que devuelve Dom4j ... ¿es esto un problema dom4j o mi comprensión de cómo funciona xpath. ya que esa consulta solo devuelve el Elemento callejero y no el elemento Comentario.

El DOM hace que el elemento de comentario a un elemento compuesto con cuatro etiquetas de dos

[Text = 'XYZ'][BR][BR][Text = 'ABC'] 

Yo asumiría que la consulta todavía debe devolver el elemento ya que debe encontrar el elemento y ejecución contiene en él, pero que doesn' t ... ...

la siguiente consulta devuelve el elemento pero vuelve mucho más que sólo el elemento, devuelve los elementos primarios, así ... que no es deseable para el problema ...

//*[contains(text(),'ABC')] 

¿Alguien sabe la consulta xpath que devolvería solo los Elementos <Street/> y <Comment/>?

+0

Por lo que puedo decir, '// * [contiene (texto(), 'ABC')]' devuelve solo el elemento ''. No devuelve ningún antepasado de '' o ''. –

Respuesta

491

La etiqueta <Comment> contiene dos nodos de texto y dos nodos <br> como secundarios.

Su expresión XPath fue

//*[contains(text(),'ABC')] 

Para descomponerlo,

  1. * es un selector que coincide con cualquier elemento (es decir, la etiqueta) - devuelve un conjunto de nodos.
  2. El [] es un condicional que opera en cada nodo individual en ese conjunto de nodos. Coincide si alguno de los nodos individuales en los que opera coincide con las condiciones dentro de los corchetes.
  3. text() es un selector que coincide con todos los nodos de texto que son hijos del nodo de contexto - devuelve un conjunto de nodos.
  4. contains es una función que funciona en una cadena. Si se pasa un conjunto de nodos, el conjunto de nodos es converted into a string by returning the string-value of the node in the node-set that is first in document order. Por lo tanto, puede hacer coincidir solo el primer nodo de texto en su elemento <Comment>, a saber, BLAH BLAH BLAH. Como eso no concuerda, no obtiene un <Comment> en sus resultados.

necesita cambiar esto a

//*[text()[contains(.,'ABC')]] 
  1. * es un selector que coincide con cualquier elemento (es decir,etiqueta) - devuelve un conjunto de nodos.
  2. El [] externo es un condicional que opera en cada nodo individual en ese conjunto de nodos; aquí opera en cada elemento del documento.
  3. text() es un selector que coincide con todos los nodos de texto que son hijos del nodo de contexto - devuelve un conjunto de nodos.
  4. El interior [] es un condicional que opera en cada nodo en ese conjunto de nodos - aquí cada nodo de texto individual. Cada nodo de texto individual es el punto de inicio para cualquier ruta en los corchetes, y también se puede hacer referencia explícitamente como . dentro de los corchetes. Coincide si alguno de los nodos individuales en los que opera coincide con las condiciones dentro de los corchetes.
  5. contains es una función que funciona en una cadena. Aquí se pasa un nodo de texto individual (.). Como se pasa el segundo nodo de texto en la etiqueta <Comment> individualmente, verá la cadena 'ABC' y podrá hacerla coincidir.
+1

Impresionante soy un poco de un novato xpath, así que déjame entender esto, text() es una función que toma la expresión contiene (., 'ABC'), ¿hay alguna posibilidad de que puedas explicarlo? Así que no hago esto un poco estúpido de nuevo;) –

+21

He editado mi respuesta para proporcionar una explicación larga. Realmente no sé mucho sobre XPath, solo experimenté un poco hasta que tropecé con esa combinación. Una vez que tuve una combinación de trabajo, hice una conjetura de lo que estaba sucediendo y busqué en el [estándar XPath] (http://www.w3.org/TR/xpath/) para confirmar lo que pensaba que estaba pasando y escribir el explicación. –

+7

+1 Buena respuesta y explicación. –

3

[contains(text(),'')] solamente devuelve verdadero o falso. No devolverá los resultados de ningún elemento.

+0

esto no funcionará si tuviera '' o '' ¿Cómo podemos recortar? – shareef

Cuestiones relacionadas