¿Cómo usar XPath contiene () aquí?

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:

 ... 
  • Type: Clip Fan
  • Feature: 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.
  • Speed Setting: 2 speeds
  • Color: Black
  • Power Consumption: 62 W
  • Height: 14.5"
  • Width: Grill Diameter: 9.5"
  • Length: 11.5"
  • Model #: CR1-0081-06
  • Item #: N82E16896817007
  • Return Policy:
...

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' y contiene (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

  • Type: Clip Fan
  • (convertido a una cadena: ” Type: Clip Fan “) lo que significa que esto:

      // ul [@ class = 'featureList' y contiene (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

    1. contains(x,y) espera que x sea ​​una cadena, y
    2. la regla XPath para convertir elementos múltiples en una cadena es esta :

      Un conjunto de nodos se convierte en una cadena devolviendo el valor de cadena 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 valor de cadena que contenga una subcadena de Model .

    Ejemplos

    XML

      
    • Model A
    • Foo
    • Foo
    • Model A

    XPaths

    • //ul[contains(li, 'Model')] selecciona el elemento ul .

      Nota: El elemento two ul no se selecciona porque el valor de cadena del primer hijo li de los two ul es Foo , que no contiene la subcadena Model .

    • //ul[li[contains(.,'Model')]] selecciona los elementos one y two ul .

      Nota: Ambos elementos ul se seleccionan porque contains() se aplica a cada li individualmente. (Por lo tanto, se evita la regla de conversión complicada de elementos múltiples a cadenas). Ambos elementos ul tienen un hijo li cuyo valor de cadena contiene la subcadena del Model – la posición del elemento li ya no importa.

    Ver también

    • Probando nodos de texto () versus valores de cadena en XPath

    Pegar mi contains ejemplo aquí:

     //table[contains(@class, "EC_result")]/tbody