2009-10-08 9 views
21

Uso mucho XPath al ubicar elementos en páginas web usando Selenium, y he dejado de usar node1 // node2 para usar node1/descenddant :: node2 más recientemente. ¿Cuál es la diferencia entre los dos métodos? ¿Es uno más eficiente que el otro?¿Cuál es la diferencia entre // node y/descenddant :: node en xpath?

fragmento

Ejemplo XML para demostrar:

<div id="books"> 
    <table> 
    <tr><td class="title">Lord of the Rings</td><td class="author">JRR Tolkein</td></tr> 
    <tr><td class="title">The Hitch-Hikers Guide to the Galaxy</td><td class="author">Douglas Adams</td></tr> 
    </table> 
</div> 

Por lo tanto, sería:

id('books')//td[@class='title']

o:

id('books')/descendant::td[@class='title']

Respuesta

24

ver http://www.w3.org/TR/xpath#path-abbrev

// es sólo una abreviatura de la d escendant :: eje

Editar

Para citar:

// párrafo es la abreviatura de/descendiente-o-self :: node()/child :: para

Es decir, se refiere a todos los para que son secundarios del nodo de contexto o de cualquier nodo que se descienda del nodo de contexto. Por lo que puedo decir, eso se traduce en cualquier para descendiente del nodo de contexto.

+1

Debería haber recorrido el TR antes de pedir. Para otros http://www.w3.org/TR/xpath#path-abbrev es la sección relevante. Sin embargo, parece que // es la abreviatura de descendiente o sí mismo, por lo que no es exactamente lo mismo.Además, la razón por la que me he mantenido alejado de usar // es que // nodo [1] no es lo mismo que/descendiente :: nodo [1] –

+1

He ampliado ese punto más arriba. // no es descendiente-o-uno, es descendiente-o-uno-mismo/infantil ... que se parece muchísimo a mi descendencia. –

+0

De acuerdo. Debidamente notificado. :) –

2

Aparte de concisión, no tengo conocimiento de ninguna diferencia.

8

Hay una diferencia en el grupo de contexto. //para[1] es la abreviatura de /descendant-or-self::node()/child::para[1], que devuelve cada para que sea el primer hijo de su padre. /descendant::para[1] devuelve solo el primer párrafo en todo el subárbol.

+0

También (// para) [1] también debería funcionar, pero no en Selenium 1, por lo que debe usar/descenddant :: para [1]. ¿Alguien sabe cómo el grupo de contexto se aplica de manera diferente entre // nodo [1] y/descendiente :: nodo [1]? –

4

En su caso

id('books')//td[@class='title'] 

y:

id('books')/descendant::td[@class='title'] 

regreso el mismo resultado.

Pero, de hecho, como ya se dijo antes, id('books')//td[@class='title'] significa id('books')/descendant-or-self::node()/td[@class='title'] que es diferente de id('books')/descendant::td[@class='title'] en concepto.

Véase la nota siguiente:

NOTA: La ubicación de la ruta // párrafo [1] no significa lo mismo que la ruta de ubicación/descendiente :: para [1]. Este último selecciona el primer elemento para para descendiente; el primero selecciona todos los elementos de para descendientes que son los primeros para hijos de sus padres.

esta nota fue tomada de http://www.w3.org/TR/xpath#path-abbrev