xml - make - xpath wildcard
XPath para seleccionar mĂșltiples etiquetas (4)
Dado este formato de datos simplificado:
<a>
<b>
<c>C1</c>
<d>D1</d>
<e>E1</e>
<f>don''t select this one</f>
</b>
<b>
<c>C2</c>
<d>D2</d>
<e>E1</e>
<g>don''t select me</g>
</b>
<c>not this one</c>
<d>nor this one</d>
<e>definitely not this one</e>
</a>
¿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?
¿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)
=> (#<XdmNode <c>C1</c>>
#<XdmNode <d>D1</d>>
#<XdmNode <e>E1</e>>
#<XdmNode <c>C2</c>>
#<XdmNode <d>D2</d>>
#<XdmNode <e>E1</e>>)
No estoy seguro si esto ayuda, pero con XSL, haría algo como:
<xsl:for-each select="a/b">
<xsl:value-of select="c"/>
<xsl:value-of select="d"/>
<xsl:value-of select="e"/>
</xsl:for-each>
y este XPath no seleccionará todos los hijos de los nodos B:
a/b/*
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.
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