xslt - w3schools - XSL: copia elementos pero elimina los espacios de nombres no utilizados
xpath en xml (4)
Esto eliminará el espacio de nombres x de la salida.
<xsl:namespace-alias result-prefix="#default" stylesheet-prefix="x" />
Recuerda hacer dos cosas cuando tratas con un espacio de nombres predeterminado. Primero mapéelo en algo en la etiqueta de la hoja de estilo, y luego elimínelo usando un alias de espacio de nombres.
Tengo algunos XML que declaran un espacio de nombres que solo se usa para atributos, como este:
<?xml version="1.0" encoding="UTF-8"?>
<a xmlns:x="http://tempuri.com">
<b>
<c x:att="true"/>
<d>hello</d>
</b>
</a>
Quiero usar XSL para crear una copia de los nodos seleccionados y sus valores, eliminando los atributos. Así que mi salida deseada es:
<?xml version="1.0" encoding="UTF-8"?>
<b>
<c />
<d>hello</d>
</b>
Tengo algunos XSL que casi hacen esto, pero parece que no puedo evitar que coloque la declaración de espacio de nombres en el elemento de nivel superior de la salida. Mi XSL es:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/">
<xsl:apply-templates select="/a/b"/>
</xsl:template>
<xsl:template match="node()">
<xsl:copy>
<xsl:apply-templates select="node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
El primer elemento de la salida es <b xmlns:x="http://tempuri.com">
lugar de <b>
. He intentado declarar el espacio de nombres en el XSL y poner el prefijo en la lista exclude-result-prefixes
, pero esto no parece tener ningún efecto. ¿Qué estoy haciendo mal?
ACTUALIZACIÓN: encontré que al declarar el espacio de nombres en el XSL y usar el atributo de extension-element-prefixes
funciona, ¡pero esto no parece correcto! Supongo que podría usar esto, ¡pero me gustaría saber por qué los exclude-result-prefixes
no funcionan!
ACTUALIZACIÓN: en realidad, parece que esta solución de prefijo de extension-element-prefixes
solo funciona con el motor XSLT integrado de XMLSpy, no con MSXML.
Intente esto (observe el atributo copy-namespaces=''no''
):
<xsl:template match="node()">
<xsl:copy copy-namespaces="no">
<xsl:apply-templates select="node()"/>
</xsl:copy>
</xsl:template>
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
xmlns:x="http://tempuri.com">
<xsl:template match="/">
<xsl:apply-templates select="/a/b"/>
</xsl:template>
<xsl:template match="*">
<xsl:element name="{local-name(.)}">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<xsl:template match="@*">
<xsl:copy/>
</xsl:template>
<!-- This empty template is not needed.
Neither is the xmlns declaration above:
<xsl:template match="@x:*"/> -->
</xsl:stylesheet>
He encontrado una explicación here .
Michael Kay escribió:
Los prefijos excluir-resultado-solo afectan los espacios de nombres copiados de la hoja de estilo por un elemento de resultado literal, no afecta la copia de los espacios de nombres de los documentos de origen.
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:x="http://tempuri.com"
exclude-result-prefixes="x"
>
<!-- the identity template copies everything 1:1 -->
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()" />
</xsl:copy>
</xsl:template>
<!-- this template explicitly cares for namespace''d attributes -->
<xsl:template match="@x:*">
<xsl:attribute name="{local-name()}">
<xsl:value-of select="." />
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>