create - xslt transformation
XSLT: agrega espacio de nombres al elemento raĆz (2)
Deberías usar la "plantilla de identidad" para esto, y siempre debes tenerla a mano. Cree un XSLT con esa plantilla, llámelo "identity.xslt", luego en el XSLT actual. Supongamos que el prefijo "malo" para el espacio de nombres que desea reemplazar, y "bueno" para el que desea reemplazarlo, entonces todo lo que necesita es una plantilla como esta (estoy en el trabajo, así que perdona el formato; Volveré a esto cuando esté en casa): ... Si eso no funciona en XSLT 1.0, use una expresión de coincidencia como "* [namespace-uri () = ''urn: bad-namespace''", y siga las instrucciones de Dimitre para crear un nuevo elemento programáticamente. En el interior, realmente necesitas aplicar la plantilla de forma recursiva ... pero realmente, lee en la plantilla de identidad.
Necesito cambiar los espacios de nombres en el elemento raíz de la siguiente manera:
documento de entrada:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<foo xsi:schemaLocation="urn:isbn:1-931666-22-9 http://www.loc.gov/ead/ead.xsd"
xmlns:ns2="http://www.w3.org/1999/xlink" xmlns="urn:isbn:1-931666-22-9"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
salida deseada:
<foo audience="external" xsi:schemaLocation="urn:isbn:1-931666-22-9
http://www.loc.gov/ead/ead.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-
instance" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="urn:isbn:1-931666-22-9">
Intenté hacerlo al copiar todo el documento y antes de dar cualquier otra instrucción de transformación, pero lo siguiente no funciona:
<xsl:template match="* | processing-instruction() | comment()">
<xsl:copy copy-namespaces="no">
<xsl:for-each select=".">
<xsl:attribute name="audience" select="''external''"/>
<xsl:namespace name="xlink" select="''http://www.w3.org/1999/xlink''"/>
</xsl:for-each>
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
Gracias por cualquier consejo!
XSLT 2.0 no es necesario para resolver este problema.
Aquí hay una solución XSLT 1.0 , que funciona igual de bien que XSLT 2.0 (simplemente cambie el atributo de version
a 2.0
):
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xlink="http://www.w3.org/1999/xlink"
exclude-result-prefixes="xlink"
>
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/*">
<xsl:element name="{name()}" namespace="{namespace-uri()}">
<xsl:copy-of select=
"namespace::*
[not(name()=''ns2'')
and
not(name()='''')
]"/>
<xsl:copy-of select=
"document('''')/*/namespace::*[name()=''xlink'']"/>
<xsl:copy-of select="@*"/>
<xsl:attribute name="audience">external</xsl:attribute>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
Cuando se aplica la transformación anterior en este documento XML :
<foo
xsi:schemaLocation="urn:isbn:1-931666-22-9 http://www.loc.gov/ead/ead.xsd"
xmlns:ns2="http://www.w3.org/1999/xlink"
xmlns="urn:isbn:1-931666-22-9"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
el resultado deseado es producido :
<foo xmlns="urn:isbn:1-931666-22-9"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xlink="http://www.w3.org/1999/xlink"
xsi:schemaLocation="urn:isbn:1-931666-22-9 http://www.loc.gov/ead/ead.xsd"
audience="external"/>