Tengo un pequeño problema con Xpath contiene con dom4j …

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 a todos los nodos que se han ABC en el texto, dado el Elemento raíz…

Por lo que el xpath que yo necesitaría para escribir sería

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

Sin embargo esto no es lo que Dom4j devuelve …. es este un dom4j problema o mi comprensión de cómo funciona xpath. desde que la consulta devuelve sólo la Calle Elemento y no el Comentario elemento.

El DOM hace el Comentario de elemento de un elemento compuesto con cuatro etiquetas de dos

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

Quiero suponer que la consulta debe devolver el elemento ya que se debe encontrar el elemento y ejecutar contiene en él, pero no … …

la consulta siguiente devuelve el elemento, sino que se vuelve mucho más que sólo el elemento, devuelve la matriz de elementos tan bien … que no es deseable para el problema …

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

Hace cualquiera sabe la consulta xpath que devolver sólo los Elementos <Street/> y <Comment/> ?

  • Como lo que yo puedo decir, //*[contains(text(),'ABC')] devuelve sólo el <Street> elemento. No devolver cualquier antepasados de <Street> o <Comment>.
InformationsquelleAutor Mike Milkin | 2010-09-07

4 Comentarios

  1. 613

    La <Comment> etiqueta contiene dos nodos de texto y dos <br> nodos como los niños.

    Su expresión xpath se

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

    Para romper este,

    1. * es un selector que coincide con cualquier elemento (es decir, la etiqueta) — devuelve un conjunto de nodos.
    2. La [] son un condicional que opera en cada nodo individual en el que el conjunto de nodos. Coincide si alguno de los nodos individuales se opera sobre coinciden con las condiciones dentro de los corchetes.
    3. text() es un selector de 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 opera sobre una cadena. Si se pasa de un conjunto de nodos, el conjunto de nodos es convertido en una cadena mediante la devolución de la cadena de valor del nodo en el conjunto de nodos que es la primera en el orden de los documentos. Por lo tanto, sólo puede coincidir con el primer nodo de texto en su <Comment> elemento, a saber,BLAH BLAH BLAH. Ya que no coincide, no se obtiene una <Comment> en sus resultados.

    Usted necesita para cambiar a

    //*[text()[contains(.,'ABC')]]
    1. * es un selector que coincide con cualquier elemento (es decir, la etiqueta) — devuelve un conjunto de nodos.
    2. El exterior [] son un condicional que opera en cada nodo individual en el que el conjunto de nodos — aquí se opera sobre cada elemento en el documento.
    3. text() es un selector de que coincide con todos los nodos de texto que son hijos del nodo de contexto — devuelve un conjunto de nodos.
    4. El interior [] son un condicional que opera en cada nodo en el que el conjunto de nodos — aquí individual de cada nodo de texto. Cada texto individual nodo es el punto de partida para cualquier ruta de acceso, en los soportes, y también puede ser referido explícitamente como . dentro de los corchetes. Coincide si alguno de los nodos individuales se opera sobre coinciden con las condiciones dentro de los corchetes.
    5. contains es una función que opera sobre una cadena. Aquí se pasa de un individuo nodo de texto (.). Desde que se aprobó el segundo nodo de texto en el <Comment> etiqueta individualmente, verá el 'ABC' cadena y ser capaz de igualar.
    • Impresionante im un poco de xpath noob, por lo que me deja este texto() es una función que toma la expresión contiene(.,’ABC’), hay una posibilidad de que usted puede explicar así que no hago esta clase de cosas estúpidas de nuevo 😉
    • He editado mi respuesta para proporcionar una larga explicación. Realmente no sé mucho acerca de XPath yo — yo sólo experimentado un poco hasta que me topé con esa combinación. Una vez tuve una combinación, me hizo adivinar lo que estaba pasando y se miró en el XPath estándar para confirmar lo que yo pensaba que estaba pasando y escribir la explicación.
    • esto funcionó para mí…excelente
    • Cómo haría usted en este caso insensible de búsqueda?
    • Por favor, hacer de esto una nueva pregunta.
    • Sé que este es un hilo viejo, pero ¿alguien puede comentar si hay una diferencia fundamental, preferiblemente con un poco de simples casos de prueba entre la respuesta dada por Ken Bloom y //*[contains(., 'ABC')]. Yo siempre había utilizado el modelo dado por Mike Milkin, pensando que era la más apropiada, pero sólo haciendo contains en el contexto actual parece ser en realidad lo que yo quiero más a menudo.
    • cómo utilizar la expresión regular aquí.digamos que mi texto es «el Resultado de(1)» y el número no es constante a puede ser cualquier número.Entonces, ¿cómo utilizar //*[contiene( text(),’ABC’] ?? yo había tratado de abajo, pero no genera nada //*[contiene( text(),’ Resultado («+».*»+»)» ‘)]
    • para el caso insensible de búsqueda de uso //*[texto([contiene(traducir(., ‘ABC’, ‘abc’), ‘abc’)]]
    • no funciona con firefox $x
    • Puede que, después de todo, de explicar cómo su solución es diferente de //*[contains(.,'ABC')]? Porque esto parece funcionar igual de bien.
    • Ahora veo, text() devuelve todos los nodos de texto del nodo actual (conjunto de nodos). Pero cuando contains() que es aplicar su primer argumento se convierte por un string() de la función. Que se lleva el primer nodo y devuelve su string-value. Es decir, //*[contains(.,'ABC')] toma en cuenta sólo el primer nodo de texto.
    • //*[text()[contains(.,'ABC')]] significa cualquier elemento para el que text()[contains(.,'ABC')] es true. text()[contains(.,'ABC')] es un conjunto de nodos de todo el texto de nodos hijos del nodo de contexto para que contains(.,'ABC') es true. Desde text()[contains(.,'ABC')] es un conjunto de nodos, se convierte en boolean boolean() de la función. Para un conjunto de nodos, boolean() devuelve true si no está vacío.
    • …Que es, //*[text()[contains(.,'ABC')]] significa cualquier elemento, el cual tiene al menos un nodo de texto niño, que contiene ABC. Lo que significa que //*[contains(.,'BLAH ABC')] no coinciden con nada. Ahora bien, //*[contains(., 'ABC')] supuestamente significa cualquier elemento que contiene ABC. Aquí al convertir a una cadena en el nodo de contexto supuestamente es tratada como un conjunto de nodos. Por lo tanto, su string-value es tomada, que es básicamente todo su texto.
    • …Como tal, //*[contains(.,'BLAH ABC')] coincide con elementos Home, Addr, y Comment.

  2. 6

    [contains(text(),'')] sólo devuelve true o false. No se devolverá ningún elemento en los resultados.

    • esto no funciona si tenía » o » ¿cómo podemos recortar ?
    • contains(text(),'JB-') no es un trabajo! conatains toma dos cadenas como argumentos – contains(**string**, **string**)! texto() no es cadena, es una función!
  3. 0

    Me tomó un poco de tiempo, pero finalmente descubrió. Xpath personalizadas que contiene algún texto de abajo, a mi me funciono perfectamente.

    //a[contains(text(),'JB-')]
    • contains(text(),'JB-') no es un trabajo! conatains toma dos cadenas como argumentos – contains(**string**, **string**)! texto() no es cadena, es una función!
  4. 0

    El documento XML:

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

    La expresión XPath:

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

    //* coincide con cualquier elemento descendiente de la nodo raíz. Es decir, cualquier elemento, sino que el nodo raíz.

    [...] es un predicado, se filtra el conjunto de nodos. Devuelve los nodos para que ... es true:

    Un predicado filtros de un conjunto de nodos […] para producir un nuevo conjunto de nodos. Para cada nodo en el conjunto de nodos a ser filtrada, la PredicateExpr se evalúa […]; si PredicateExpr evalúa a true para que el nodo, el nodo está incluido en el nuevo conjunto de nodos; de lo contrario, no está incluido.

    contains('haystack', 'needle') devuelve true si haystack contiene needle:

    Función: boolean contains(string, string)

    La contiene la función devuelve true si el primer argumento de cadena que contiene el segundo argumento de cadena, y en caso contrario, devuelve false.

    Pero contains() toma una cadena como primer parámetro. Y se pasa de los nodos. Para tratar con la que cada nodo o conjunto de nodos que se pasa como primer parámetro es convertidos a una cadena por la string() función:

    Un argumento es convertido al tipo de cadena como si llamando a la función string.

    string() función devuelve string-value de el primer nodo:

    Un conjunto de nodos se convierte en una cadena mediante la devolución de la cadena de valor del nodo en el conjunto de nodos que es la primera en el orden del documento. Si el conjunto de nodos está vacío, se devuelve una cadena vacía.

    string-value de un nodo de elemento:

    La cadena de valor de un nodo de elemento es la concatenación de la cadena de valores de todos los nodos de texto descendientes de un nodo de elemento en el orden del documento.

    string-value de un nodo de texto:

    La cadena de valor de un nodo de texto es el carácter de los datos.

    Así que, básicamente string-value es que todo el texto está contenido en un nodo (concatenación de todos los descendientes de los nodos de texto).

    text() es una prueba de nodo que coincide con cualquier nodo de texto:

    La prueba de nodo de texto() es verdadera para cualquier nodo de texto. Por ejemplo, child::text() selecciona el texto de nodos hijos del nodo de contexto.

    Tener que dijo, //*[contains(text(), 'ABC')] coincide con cualquier elemento (pero el nodo raíz), el primer nodo de texto que contiene ABC. Desde text() devuelve un conjunto de nodos que contiene todos los niños de los nodos de texto del nodo de contexto (en relación con los que se evalúa una expresión). Pero contains() toma sólo la primera. Así que, por el documento sobre la ruta coincide con la Street elemento.

    La siguiente expresión //*[text()[contains(., 'ABC')]] coincide con cualquier elemento (pero el nodo raíz), que tiene al menos un hijo nodo de texto, que contiene ABC. . representa el nodo de contexto. En este caso, es un niño nodo de texto de cualquier elemento, sino que el nodo raíz. Así que, por el documento sobre la ruta coincide con la Street, y el Comment elementos.

    Ahora bien, //*[contains(., 'ABC')] coincide con cualquier elemento (pero el nodo raíz) que contiene ABC (en la concatenación de los descendiente de los nodos de texto). Para el documento anterior coincide con la Home, el Addr, el Street, y el Comment elementos. Como tal, //*[contains(., 'BLAH ABC')] coincide con el Home, el Addr, y el Comment elementos.

Dejar respuesta

Please enter your comment!
Please enter your name here