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 del nodo raíz . Es decir, cualquier elemento menos el nodo raíz.
[...]
es un predicado , filtra el conjunto de nodos. Devuelve nodos para los cuales ...
es true
:
Un predicado filtra un conjunto de nodos [...] para producir un nuevo conjunto de nodos. Para cada nodo en el conjunto de nodos a filtrar, se evalúa el PredicateExpr [...]; si PredicateExpr se evalúa como verdadero para ese nodo, el nodo se incluye en el nuevo conjunto de nodos; de lo contrario, no está incluido.
contains('haystack', 'needle')
devuelve true
si haystack
contiene needle
:
Función: boolean contiene (cadena, cadena)
La función contiene devuelve verdadero si la primera cadena de argumento contiene la segunda cadena de argumento y, de lo contrario, devuelve falso.
Pero contains()
toma una cadena como primer parámetro. Y ha pasado nodos. Para lidiar con eso, cada nodo o conjunto de nodos pasado como primer parámetro se convierte en una cadena por la string()
función:
Un argumento se convierte para escribir una cadena como llamando a la función de cadena.
string()
función devuelve string-value
del primer nodo :
Un conjunto de nodos se convierte en una cadena al devolver el valor de cadena del nodo en el conjunto de nodos que está primero 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 :
El valor de cadena de un nodo de elemento es la concatenación de los valores de cadena de todos los descendientes de nodo de texto del nodo de elemento en orden de documento.
string-value
de un nodo de texto :
El valor de cadena de un nodo de texto son los datos de caracteres.
Entonces, básicamente string-value
todo el texto está contenido en un nodo (concatenación de todos los nodos de texto descendientes).
text()
es una prueba de nodo que coincide con cualquier nodo de texto:
El texto de prueba de nodo () es verdadero para cualquier nodo de texto. Por ejemplo, child :: text () seleccionará los hijos del nodo de texto del nodo de contexto.
Dicho esto, //*[contains(text(), 'ABC')]
coincide con cualquier elemento (excepto el nodo raíz), cuyo primer nodo de texto contiene ABC
. Dado que text()
devuelve un conjunto de nodos que contiene todos los nodos de texto secundarios del nodo de contexto (en relación con el cual se evalúa una expresión). Pero contains()
solo toma el primero. Entonces, para el documento de arriba, la ruta coincide con el Street
elemento.
La siguiente expresión //*[text()[contains(., 'ABC')]]
coincide con cualquier elemento (pero el nodo raíz), que tiene al menos un nodo de texto secundario, que contiene ABC
. .
representa el nodo de contexto. En este caso, es un nodo de texto hijo de cualquier elemento que no sea el nodo raíz. Entonces, para el documento de arriba, la ruta coincide con Street
los Comment
elementos.
Ahora bien, //*[contains(., 'ABC')]
coincide con cualquier elemento (pero el nodo raíz) que contiene ABC
(en la concatenación de los nodos de texto descendientes). Para el documento anterior, coincide con los elementos Home
, the Addr
, the Street
y the Comment
. Como tal, //*[contains(., 'BLAH ABC')]
coincide con los elementos Home
, the Addr
y the Comment
.
//*[contains(text(),'ABC')]
solo devuelve el<Street>
elemento. No devuelve ningún antepasado de<Street>
o<Comment>
.