XPath para seleccionar múltiples tags

Dado este formato de datos simplificado:

  C1 D1 E1 don't select this one   C2 D2 E1 don't select me  not this one nor this one definitely not this one  

¿Cómo seleccionarías todas las C s, D s y E s que son elementos B de B ?

Básicamente, algo como:

 a/b/(c|d|e) 

En mi propia situación, en lugar de solo a/b/ , la consulta que conduce a la selección de esos nodos C , D , E es en realidad bastante compleja, así que me gustaría evitar hacer esto:

 a/b/c|a/b/d|a/b/e 

es posible?

Una respuesta correcta es :

 /a/b/*[self::c or self::d or self::e] 

Tenga en cuenta que esto

 a/b/*[local-name()='c' or local-name()='d' or local-name()='e'] 

es a la vez demasiado largo e incorrecto . Esta expresión XPath seleccionará nodos como:

 OhMy:c NotWanted:d QuiteDifferent:e 

Puede evitar la repetición con una prueba de atributo en su lugar:

 a/b/*[local-name()='c' or local-name()='d' or local-name()='e'] 

Contrariamente a la opinión antagónica de Dimitre, lo anterior no es incorrecto en un vacío donde el OP no ha especificado la interacción con los espacios de nombres. El eje self:: es restrictivo del espacio de nombre, local-name() no lo es. Si la intención del OP es capturar c|d|e independientemente del espacio de nombres (lo que sugeriría es incluso un escenario probable dada la naturaleza O del problema), entonces es “otra respuesta que todavía tiene algunos votos positivos” que es incorrecta .

No puede ser definitivo sin definición, aunque estoy muy contento de borrar mi respuesta como genuinamente incorrecta si el OP aclara su pregunta de tal manera que soy incorrecto.

¿Por qué no a/b/(c|d|e) ? Acabo de probar con la biblioteca de Saxon XML (envuelta muy bien con algunos Clojure bondad), y parece funcionar. abc.xml es el documento descrito por OP.

 (require '[saxon :as xml]) (def abc-doc (xml/compile-xml (slurp "abc.xml"))) (xml/query "a/b/(c|d|e)" abc-doc) => (#C1> #D1> #E1> #C2> #D2> #E1>) 

No estoy seguro si esto ayuda, pero con XSL, haría algo como:

      

y este XPath no seleccionará todos los hijos de los nodos B:

 a/b/*