¿Cómo selecciono elementos secundarios de cualquier profundidad usando XPath?

101

Supongamos que tengo esto (simplificado):

<form id="myform">
    <!-- some input fields -->
    <input type="submit" value="proceed"/>
</form>

Entonces puedo seleccionar el botón enviar por XPath //form[@id='myform']/input[@type='submit']. Excelente.

Sin embargo, mis plantillas pueden cambiar y quiero ser flexible en la profundidad en la que se encuentra el botón de enviar. Podría colocarse en una tabla, como esta:

<form id="myform">
    <!-- some input fields -->
    <table><tr><td>
           <input type="submit" value="proceed"/>
    </td></tr></table>
</form>

Sé que puedo seleccionar elementos que son nietos, pero no puedo seleccionar grand-grand-grand -...- hijos de ninguna profundidad. P.ej:

  • //form[@id='myform']/*/input[@type='submit'] solo selecciona nietos, no más profundidades.
  • //form[@id='myform']/*/*/input[@type='submit'] Solo selecciona nietos-nietos, ni más ni menos profundidad.
  • //form[@id='myform']/**/input[@type='submit'] no es válido.

Entonces, ¿cómo selecciono este botón de envío de manera confiable sin usar ID de elemento?

Gertvdijk
fuente

Respuestas:

157

Ya casi estás ahí. Simplemente use:

//form[@id='myform']//input[@type='submit']

El //atajo también se puede utilizar dentro de una expresión.

Nwellnhof
fuente
C # no parece entender esta notación. //form//inputdevuelve nulo en C # mientras que Chrome puede encontrar 35 entradas usando el mismo xpath
Achilles
1
Mi último comentario se discute aquí: stackoverflow.com/questions/23232671/…
Achilles
14

Si está utilizando XmlDocument y XmlNode.

Decir:

XmlNode f = root.SelectSingleNode("//form[@id='myform']");

Utilizar:

XmlNode s = f.SelectSingleNode(".//input[@type='submit']");

Depende de la herramienta que uses. Pero .// seleccionará cualquier hijo, cualquier profundidad de un nodo de referencia.

sk
fuente
Funciona bien dentro de Powershell usando el comando SelectSingleNode en un determinado nodo XML extraído anteriormente.
Gizmo3399
9
//form/descendant::input[@type='submit']
luis largo
fuente
6
agregue alguna descripción.
piyushj
0

Además, puedes hacerlo con selectores css:

form#myform input[type='submit']

espacio entre elementos en elector css significa buscar entrada [tipo = 'enviar'] esos elementos en cualquier profundidad del formulario principal # elemento myform

Mahsum Akbas
fuente