xml - expressions - xpath wildcard
¿Cómo usar XPath contiene() aquí? (4)
Estoy tratando de aprender xpath. Miré los otros ejemplos de contains () por aquí, pero nada que use un operador AND. No puedo hacer que esto funcione:
//ul[@class=''featureList'' and contains(li, ''Model'')]
En:
...
<ul class="featureList">
<li><b>Type:</b> Clip Fan</li><li><b>Feature:</b> Air Moved: 65 ft.
Amps: 1.1
Clip: Grips any surface up to 1.63"
Plug: 3 prong grounded plug on heavy duty model
Usage: Garage, Workshop, Dorm, Work-out room, Deck, Office & more.</li><li><b>Speed Setting:</b> 2 speeds</li><li><b>Color:</b> Black</li><li><b>Power Consumption:</b> 62 W</li><li><b>Height:</b> 14.5"</li><li><b>Width:</b> Grill Diameter: 9.5"</li><li><b>Length:</b> 11.5"</li>
<li><b>Model #: </b>CR1-0081-06</li>
<li><b>Item #: </b>N82E16896817007</li>
<li><b>Return Policy: </b></li>
</ul>
...
Pegar mi contains
ejemplo aquí:
//table[contains(@class, "EC_result")]/tbody
Solo busca el primer elemento secundario en la consulta que tiene en lugar de buscar cualquier elemento hijo li
que pueda contener el texto ''Model''
. Lo que necesita es una consulta como la siguiente:
//ul[@class=''featureList'' and ./li[contains(.,''Model'')]]
Esta consulta le dará los elementos que tienen una class
de featureList
con uno o más hijos li
que contienen el texto, ''Model''
.
Ya di mi +1 a la solución de Jeff Yates.
Aquí hay una explicación rápida de por qué su enfoque no funciona. Esta:
//ul[@class=''featureList'' and contains(li, ''Model'')]
encuentra una limitación de la función contains()
(o cualquier otra función de cadena en XPath, para el caso).
El primer argumento se supone que es una cadena. Si le das de comer una lista de nodos (dándole " li
" hace eso), se debe llevar a cabo una conversión a cadena. Pero esta conversión se realiza para el primer nodo en la lista solamente.
En su caso, el primer nodo en la lista es <li><b>Type:</b> Clip Fan</li>
(convertido a una cadena: " Type: Clip Fan
") lo que significa que esto:
//ul[@class=''featureList'' and contains(li, ''Type'')]
¡realmente seleccionaría un nodo!
Esta es una nueva respuesta a una vieja pregunta sobre un error común sobre contains()
en XPath ...
Resumen: contains()
significa que contiene una subcadena , que no contiene un nodo .
Explicación detallada
Este XPath a menudo se malinterpreta:
//ul[contains(li, ''Model'')]
Interpretación errónea: seleccione los elementos ul
que contengan un elemento li
con el Model
en él.
Esto está mal porque
-
contains(x,y)
espera quex
sea una cadena, y la regla XPath para convertir elementos múltiples en una cadena es this :
Un conjunto de nodos se convierte en una cadena devolviendo el string-value de string-value del nodo en el conjunto de nodos que está primero en orden de documento . Si el conjunto de nodos está vacío, se devuelve una cadena vacía.
Interpretación correcta: seleccione los elementos ul
cuyo primer hijo li
tenga un string-value que contenga una subcadena de Model
.
Ejemplos
XML
<r>
<ul id="one">
<li>Model A</li>
<li>Foo</li>
</ul>
<ul id="two">
<li>Foo</li>
<li>Model A</li>
</ul>
</r>
XPaths
//ul[contains(li, ''Model'')]
selecciona el elementoul
.Nota: El elemento
two
ul
no se selecciona porque el valor de cadena del primer hijoli
de lostwo
ul
esFoo
, que no contiene la subcadenaModel
.//ul[li[contains(.,''Model'')]]
selecciona los elementosone
ytwo
ul
.Nota: Ambos elementos
ul
se seleccionan porquecontains()
se aplica a cadali
individualmente. (Por lo tanto, se evita la regla de conversión complicada de elementos múltiples a cadenas). Ambos elementosul
tienen un hijoli
cuyo valor de cadena contiene la subcadena delModel
- la posición del elementoli
ya no importa.