XSLT elimina ns de XML

Aug 29 2020

Tengo dificultades para generar el XML esperado usando XSLT en el que estoy tratando de lograr el control de versiones de XML y quiero eliminar la etiqueta de identificación del XML. XSLT elimina la etiqueta pero se agrega xmlns=""como un atributo de cada etiqueta en la salida.

XML se ve así

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Customer xmlns="urn:com:xmlschema:service:v1.1:Address.xsd">
    <ID>123</ID>
    <Status>PRESENT</Status>
    <InternetAddress>00:00:00:00:00</InternetAddress>
    <PhysicalAddress>SOME ADDRESS</PhysicalAddress>
    <FamilyMember>8</FamilyMember>
</Customer>

XSLT

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns="urn:com:xmlschema:service:v1.1:Address.xsd"
                exclude-result-prefixes="#all" >
    <xsl:output method="xml" indent="yes"/>
    <xsl:strip-space elements="*"/>
    <xsl:template match="*">
        <xsl:element name="{local-name(.)}">
            <xsl:apply-templates select="@* | node()"/>
        </xsl:element>
    </xsl:template>
    <xsl:template match="@*">
        <xsl:attribute name="{local-name(.)}">
            <xsl:value-of select="."/>
        </xsl:attribute>
    </xsl:template>
    <xsl:template match="ns:Customer">
        <Customer xmlns="urn:com:xmlschema:service:v2.1:Address.xsd">
            <xsl:apply-templates select="@*|node()"/>
        </Customer>
    </xsl:template>
    <xsl:template match="ns:ID"/>
</xsl:stylesheet>

Rendimiento esperado

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Customer xmlns="urn:com:xmlschema:service:v2.1:Address.xsd">
    <Status>PRESENT</Status>
    <InternetAddress>00:00:00:00:00</InternetAddress>
    <PhysicalAddress>SOME ADDRESS</PhysicalAddress>
    <FamilyMember>8</FamilyMember>
</Customer>

XSLT generado

<?xml version="1.0" encoding="UTF-8"?>
<Customer xmlns="urn:com:xmlschema:service:v2.1:Address.xsd">
   <Status xmlns="">PRESENT</Status>
   <InternetAddress xmlns="">00:00:00:00:00</InternetAddress>
   <PhysicalAddress xmlns="">SOME ADDRESS</PhysicalAddress>
   <FamilyMember xmlns="">8</FamilyMember>
</Customer>

xmlns=""Quiero quitar. Amablemente sugiera dónde estoy cometiendo un error.

Respuestas

2 zx485 Aug 29 2020 at 08:38

Estaba intentando eliminar los espacios de nombres de los elementos secundarios de su elemento raíz. Eso funcionó, de ahí el xmlns=''. Pero xmlns=...establece un espacio de nombres predeterminado para todos sus hijos, que estaba tratando de cancelar en sus dos primeras plantillas.

Para obtener el resultado que desea, puede deshacerse de estas plantillas y simplemente usar la plantilla de eliminación con una plantilla que cambia el espacio de nombres de todos los elementos al nuevo:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns="urn:com:xmlschema:service:v1.1:Address.xsd" exclude-result-prefixes="#all" >
    <xsl:output method="xml" indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="ns:*">
        <xsl:element name="{local-name()}" namespace="urn:com:xmlschema:service:v2.1:Address.xsd">
            <xsl:apply-templates select="@*|node()"/>
        </xsl:element>
    </xsl:template>
    
    <xsl:template match="ns:ID"/>
</xsl:stylesheet>

Su resultado es el deseado (supuestamente):

<?xml version="1.0" encoding="UTF-8"?>
<Customer xmlns="urn:com:xmlschema:service:v2.1:Address.xsd">
   <Status>PRESENT</Status>
   <InternetAddress>00:00:00:00:00</InternetAddress>
   <PhysicalAddress>SOME ADDRESS</PhysicalAddress>
   <FamilyMember>8</FamilyMember>
</Customer>

Esto incluso funciona en XSLT-1.0.