XSLT remove ns do XML

Aug 29 2020

Lutando para gerar o XML esperado usando o XSLT no qual estou tentando obter o controle de versão do XML e quero remover a tag de identificação do XML. XSLT remove tag, mas foi adicionado xmlns=""como um atributo de cada tag na saída.

XML fica assim

<?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>

Saída esperada

<?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 gerado

<?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=""Eu quero remover. Por favor, sugira onde estou cometendo um erro.

Respostas

2 zx485 Aug 29 2020 at 08:38

Você estava tentando remover os namespaces dos filhos do seu elemento raiz. Isso funcionou, daí o xmlns=''. Mas o xmlns=...define um namespace padrão para todos os seus filhos - que você estava tentando cancelar em seus dois primeiros modelos.

Para obter a saída desejada, você pode se livrar desses modelos e apenas usar o modelo de remoção com um modelo que altera o namespace de todos os elementos para o novo:

<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>

Seu resultado é o desejado (supostamente):

<?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>

Isso funciona até no XSLT-1.0.