2012-06-02 17 views
27

tengo una siguiente xml:XPath seleccionar todos los elementos entre dos elementos específicos

<doc> 
    <divider /> 
    <p>text</p> 
    <p>text</p> 
    <p>text</p> 
    <p>text</p> 
    <p>text</p> 
    <divider /> 
    <p>text</p> 
    <p>text</p> 
    <divider /> 
    <p>text</p> 
    <divider /> 
</doc> 

deseo seleccionar todos los nodos p después primer elemento divisor hasta el próximo ocurrencia de elemento divisor. Intenté con el siguiente xpath:

//divider[1]/following-sibling::p[following::divider] 

pero el problema es que selecciona todos los elementos p antes del último elemento divisor. No estoy seguro de cómo hacerlo usando XPath 1.

Respuesta

24

mismo concepto que bytebuster, sino un XPath diferente:

/*/p[count(preceding-sibling::divider)=1] 
+0

¡Excelente idea! 'count' es más idiomático ya que el' 1' se usa solo una vez. – bytebuster

4

¿Qué pasa con la selección de todos los p tener exactamente uno elemento divider como preceding-sibling?

//doc/p[preceding-sibling::divider[1] and not (preceding-sibling::divider[2])] 
14

Aquí es una expresión XPath en general:

/*/divider[$k] 
    /following-sibling::p 
     [count(.|/*/divider[$k+1]/preceding-sibling::p) 
     = 
     count(/*/divider[$k+1]/preceding-sibling::p) 
     ] 

Si sustituye $k con 1 entonces exactamente el querido p se seleccionan los nodos.

si sustituye $k con 2 entonces todos los elementos p entre el 2 y 3 divider, ..., etc.

Explicación:

Esta es una sencilla aplicación de la Kayessian XPath 1.0 fórmula para la intersección del conjunto de nodos:

$ns1[count(.|$ns2) = count($ns2)] 

se da acceso a todos los nodos que pertenecen a ambos a los conjuntos de nodos $ns1 y $ns2.

En este caso específico sustituimos $ns1 con:

/*/divider[$k]/following-sibling::p 

y sustituimos $ns2 con:

/*/divider[$k+1]/preceding-sibling::p 
+0

+1 Buena implementación de '' Método de Kayessian''. – Cylian

+0

@Cylian: De nada. –

4

Creo que hay una solución mucho más simple y probablemente más rápido: desea que todos los hermanos anteriores de el segundo divisor que tiene al menos un divisor hermano anterior:

/doc/divider[2]/preceding-sibling::p[preceding-sibling::divider] 

Se vuelve un poco más complejo, por supuesto, si quieres encontrar los parametros entre el segundo y el tercer divisor: entonces quieres algo más parecido a la solución de Daniel Haley.

Cuestiones relacionadas