2010-07-28 23 views
32

Hola tengo un archivo XML que está estructurado de la siguiente manera:¿Qué es xpath para seleccionar un rango de nodos?

<foo> 
    <bar></bar> 
    <bar></bar> 
    ... 
</foo> 

No sé cómo agarrar una serie de nodos. podría alguien darme un ejemplo de una expresión xpath que agarra los nodos de barras 100-200.

+0

Buena pregunta (+1). Vea mi respuesta para una breve expresión XPath seleccionando exactamente los nodos requeridos. –

Respuesta

53

Uso:

/*/bar[position() >= 100 and not(position() > 200)] 

hacer la nota:

  1. Exactamente los bar elementos en la posición 100 a 200 (ambos inclusive) son seleccionados.

  2. La evaluación de estas expresiones XPath puede ser mucho más rápida que una expresión utilizando la abreviatura //, porque esta última causa un escaneo completo del árbol cuya raíz es el nodo de contexto. Siempre trate de evitar el uso de la abreviatura // en los casos en que esto sea posible.

+0

Si lo recuerda, ¿podría entrar en su segundo punto? ¿// y/*/devolverán los mismos resultados, y aún así el último es más rápido? –

+0

@BramVanroy, Tanto '//' como '/ * /' son expresiones XPath sintácticamente inválidas. Supongo que querías decir '// *' y/*/*. La respuesta es que, en este caso específico, el tiempo empleado debe ser aproximadamente el mismo. Sin embargo, si se trata de predicados, la expresión que incluye '//' tendrá que escanear un árbol completo (incluso los descendientes de los nodos seleccionados finalmente) y filtrar cada nodo, mientras que en el caso de la expresión exacta se evitará tal escaneo. Tenga en cuenta también que hay ** algunos ** procesadores XPath que están altamente optimizados para procesar '// *' y expresiones similares de manera eficiente. –

8
//foo/bar[100 <= position() and position() < 200] 
4

No es fn:subsequence la mejor manera?

subsequence(/foo/bar, 100, 101) 

devuelve todos los elementos de la posición 100 a la 200, es decir, 101 elementos (o menos si la secuencia fuente es más corta).

+0

Si bien esto puede ser correcto, el uso de la posición() en un predicado es más general ya que se puede aplicar en múltiples niveles. Ej:/foo/bar [2 <= posición() y posición() <5]/x [5 <= posición() y posición() <10] –

+0

@DonaldRich Sí - pero eso causa 'position()' a se evaluará en cada elemento de la secuencia (que puede ser mucho más que los 100 elementos finalmente seleccionados), mientras que 'subsequence()' se llamará solo una vez. De todos modos, esta charla se trata de '¿cómo podemos seleccionar todos los nodos en la secuencia en las posiciones 100 a 200', y ** no ** sobre '¿podemos evitar el uso de 'posición()' para cada posible requisito de filtrado de secuencia?' Mi respuesta se relaciona directamente con, y solo a, la pregunta hecha. – CiaPan

+0

@DonaldRich BTW, siempre que tengamos _have_ 'subsequence()' disponible, su consulta se puede reescribir fácilmente como 'subsequence (subsequence (/ foo/bar, 2, 3)/x, 5, 5)' – CiaPan

Cuestiones relacionadas