Hay una nota importante en el documento W3C sobre XPath:
XML Path Language (XPath) Version 1.0
2 Location Paths
2.5 Abbreviated Syntax
NOTA: la vía de ubicación //para[1]
no significa que la misma como la ruta de ubicación /descendant::para[1]
. Este último selecciona el primer elemento descendente para
; el primero selecciona todos los descendientes para
elementos que son los primeros para hijos de sus padres.
Eso significa que el doble barra dentro de la trayectoria no es sólo un atajo para /descendant-or-self::node()/
sino también un punto de partida para el siguiente nivel de una iteración árbol XML, lo que implica la expresión paso a la derecha de //
se vuelve a ejecutar en cada descendiente del nodo de contexto actual.
Así que el significado exacto del predicado en este camino
//div[ descendant::table/descendant::td[4] ]
es:
- construir una secuencia de todos
<table>
nodos descendientes a la corriente <div>
,
- para cada uno de esos
<table>
acumulación una secuencia de todos los elementos descendentes <td>
y concatenándolos en una única secuencia e,
- filtra esa secuencia para su cuarto elemento.
Finalmente, la ruta devuelve todos los elementos <div>
del documento, que tienen al menos cuatro celdas de datos en todas sus tablas anidadas. Y dado que hay tablas en el documento que tienen 4 celdas o más (incluidas las celdas de las tablas anidadas, por supuesto), la expresión completa selecciona sus respectivos antecesores <div>
.
Por otro lado el predicado en
//div[ //table//td[4] ]
significa:
- escanear toda la estructura del documento para
<table>
elementos (más precisamente, probar el nodo raíz y el descendiente de cada raíz si tiene una <table>
hijo),
- para cada tabla encontrada escanee su subárbol para elementos que tienen un cuarto subelemento
<td>
(es decir, pruebe si la tabla o cualquiera de sus descendientes tiene al menos cuatro <td>
niños).
Tenga en cuenta que la subexpresión del predicado no depende del nodo de contexto. Es una ruta global, que se resuelve en una secuencia de nodos (posiblemente vacía), por lo que el valor booleano del predicado depende solo de la estructura del documento. Si es verdadero, la ruta completa devuelve una secuencia de todos los elementos <div>
en el documento, sino la secuencia vacía.
Finalmente el predicado sería cierto si y sólo si había un elemento en cualquier mesa, que tiene 4 (al menos) las celdas de datos.
Y hasta donde puedo ver todas las filas <tr>
contienen dos o tres celdas - no hay elemento con 4 o más hijos <td>
, por lo que la subexpresión del predicado devuelve una secuencia vacía, el predicado es falso y toda la ruta se filtra fuera. El resultado es: nada (secuencia vacía).
Gracias, pero su versión arreglada tampoco funciona. Comprueba la URL de esta página con XPather/FF3.6.28 (disponible en PortableApps). La sintaxis completa devuelve 9 resultados, mientras que la breve con punto 0 resulta. ¿Hay algún otro (sitio/programa) con un motor diferente para verificar? – Maksee
Considere publicar una muestra del XML o HTML que está consultando con XPath. Creo que he dado la explicación correcta sobre lo que '//' representa, también vea http://www.w3.org/TR/xpath/#path-abbrev. La larga sintaxis con 'descenddant-or-self :: node()' es difícil de leer y escribir, así que pude cometer dos errores al escribir las muestras de ruta, espero haberlas corregido ahora. Todavía hay una diferencia entre '[descenddant :: table/descenddant :: td [4]]' y '[.// table // td [4]]', lo mejor es hablar de eso con datos de muestra. –
Los datos de muestra son esta página (lo siento si no estaba claro), por lo que el contenido de esta página estamos discutiendo en :) – Maksee