¿Cómo encontrarías todos los nodos entre dos H3 usando XPATH?

¿Cómo encontrarías todos los nodos entre dos H3 usando XPATH?

En XPath 1.0, una forma de hacerlo es mediante el uso del método Kayessian para la intersección de conjuntos de nodos :

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

La expresión anterior selecciona exactamente los nodos que forman parte tanto del conjunto $ns1 como del conjunto $ns2 .

Para aplicar esto a la pregunta específica , digamos que necesitamos seleccionar todos los nodos entre el segundo y tercer elemento h3 en el siguiente documento XML:

  

Title T31

Title T32

Title T33

Title T34

Title T35

Tenemos que sustituir $ns1 con :

 /*/h3[2]/following-sibling::node() 

y para sustituir $ns2 con :

 /*/h3[3]/preceding-sibling::node() 

Por lo tanto, la expresión XPath completa es :

 /*/h3[2]/following-sibling::node() [count(.|/*/h3[3]/preceding-sibling::node()) = count(/*/h3[3]/preceding-sibling::node()) ] 

Podemos verificar que esta es la expresión correcta de XPath:

       

Cuando se aplica esta transformación en el documento XML presentado anteriormente, se produce el resultado deseado y correcto :

   

II. Solución XPath 2.0 :

Use el operador de intersect :

  /*/h3[2]/following-sibling::node() intersect /*/h3[3]/preceding-sibling::node() 

Otra solución XPath 1.0 cuando sabe que ambas marcas son el mismo elemento (este caso h3 ):

 /html/body/h3[2]/following-sibling::node() [not(self::h3)] [count(preceding-sibling::h3)=2] 

Una solución más general, en XPath 2.0, suponiendo que desea nodos en todas las profundidades de árbol entre los dos elementos h3, que no necesariamente serían hermanos.

 /path/to/first/h3/following::node()[. << /path/to/second/h3] 

Sobre la base de la excelente respuesta de dimitre-novatchev , puedo seguir con la siguiente solución que, en lugar de hardcoding [2] y [3] para los diferentes H3s, solo doy el contenido del encabezado del primer elemento.

 //h3[text()="Main Page Section Heading"]/following-sibling::node() [ count(.|//h3[text()="Main Page Section Heading"]/following-sibling::h3[1]/preceding-sibling::node()) = count(//h3[text()="Main Page Section Heading"]/following-sibling::h3[1]/preceding-sibling::node()) ] 

Sin embargo, si quisiera ir más allá, sería capaz de lidiar con el escenario cuando estoy viendo el último H3 y obtener todo después, en el caso anterior no puedo obtener lo que sigue al último H3.

Existe otra gran solución genérica que utiliza claves, suponiendo que sus tags

tienen una propiedad única (por ejemplo, su texto o un atributo de id ):

      

Agrupa todas las tags por su