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 quexsea 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
twoulno se selecciona porque el valor de cadena del primer hijolide lostwoulesFoo, que no contiene la subcadenaModel.//ul[li[contains(.,''Model'')]]selecciona los elementosoneytwoul.Nota: Ambos elementos
ulse seleccionan porquecontains()se aplica a cadaliindividualmente. (Por lo tanto, se evita la regla de conversión complicada de elementos múltiples a cadenas). Ambos elementosultienen un hijolicuyo valor de cadena contiene la subcadena delModel- la posición del elementoliya no importa.