¿Cómo puedo, dado un DOM W3C (aplicación por defecto de Java, específicamente) cambiar el espacio de nombres de cada elemento/atributo/nodo en ese DOM? Eficientemente, preferiblemente.
No creo que haya una solución eficiente que también sea robusta. No puede simplemente cambiar el nombre de algo en el elemento raíz. Tenga en cuenta estos documentos:
Doc1
<?xml version="1.0" encoding="UTF-8"?>
<root xmlns="urn:all" xmlns:f="urn:fleet" xmlns:m="urn:mission">
<f:starfleet>
<m:bold>
<f:ship name="Enterprise" />
</m:bold>
</f:starfleet>
</root>
Doc2
<?xml version="1.0" encoding="UTF-8"?>
<root xmlns="urn:all">
<starfleet xmlns="urn:fleet">
<bold xmlns="urn:mission">
<ship xmlns="urn:fleet" name="Enterprise" />
</bold>
</starfleet>
</root>
Doc3
<?xml version="1.0" encoding="UTF-8"?>
<r:root xmlns:r="urn:all">
<r:starfleet xmlns:r="urn:fleet">
<r:bold xmlns:r="urn:mission">
<r:ship xmlns:r="urn:fleet" name="Enterprise" />
</r:bold>
</r:starfleet>
</r:root>
Estos tres documentos son equivalentes en un espacio de nombres DOM-conscientes. Puede ejecutar el mismo namespaced XPath queries contra cualquiera de ellos.
Desde el DOM permite especificar exactamente cómo se deben namespaced nodos, no existe un cajón de sastre, llamada de un solo paso para cambiar un espacio de nombres. Debe recorrer el DOM, teniendo en cuenta no solo los valores de prefijo y URI, sino también su scope en un momento determinado.
Este XSLT se puede utilizar con un Transformer para cambiar elementos de espacios de nombres como urn:fleet
ser espacio de nombres como urn:new
:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:f="urn:fleet" version="1.0">
<xsl:output method="xml" indent="yes" />
<xsl:template match="*">
<xsl:copy>
<xsl:copy-of select="@*" />
<xsl:apply-templates />
</xsl:copy>
</xsl:template>
<xsl:template match="f:*">
<xsl:variable name="var.foo" select="local-name()" />
<xsl:element namespace="urn:new" name="{$var.foo}">
<xsl:copy-of select="@*" />
<xsl:apply-templates />
</xsl:element>
</xsl:template>
</xsl:stylesheet>
Advertencias: sería necesario ajustar aún más para manejar atributos de espacios de nombres; las declaraciones urn:fleet
colgantes pueden dejarse atrás, lo cual es complicado, pero en gran medida no tiene importancia; Probablemente otras cosas en las que no había pensado.
XSL es probablemente la solución más fácil, y debe trabajar en JAXP. ¿Qué intentaste y cómo falló? – skaffman