juankinspain
juankinspain

Reputation: 5

XSL for removing or changing empty xmlns on xml document

A synchronous SOAP web service is answering my request with a xml document which has an element with an empty xmlns attribute (<element xmlns="">value</element>). This is, of course, messing with the program in charge of processing this response.

I would like to apply an XSL transformation to get rid of the empty xmlns or changing it to the proper namespace. So far XSL stylesheets I have found here or in other websites don't work or make the children of the fixed element to have now an empty xmlns. My input xml document is as follow:

<?xml version="1.0" encoding="utf-8"?>
    <rootElement xmlns="http://tempuri.org/">
        <level1>
            <level2 xmlns="">
                <child1 id="aNumber" desc="aString">
                    <name>name1</name>
                    <code>code1</code>
                </child1>
                <child2 desc="aString">
                    <field1>field1</field1>
                    <field2>field2</field2>
                </child2>
            </level2>
        </level1>
    </rootElement>

The best output I got so far with some xsl stylesheets found here got me something like this:

<?xml version="1.0" encoding="UTF-8"?>
<rootElement xmlns="http://tempuri.org/">
        <level1>
            <level2>
                  <child1 xmlns="" desc="aString" id="aNumber">
                        <name>name1</name>
                        <code>code1</code>
                  </child1>
                  <child2 xmlns="" desc="aString">
                        <field1>field1</field1>
                        <field2>field2</field2>
                  </child2>
            </level2>
        </level1>
    </rootElement>

level2 is fixed but now child1 and child 2 have each an empty xmlns. This is making my program to fail too. The best and simplest stylesheet that got me so far is this one:

<xsl:stylesheet version='2.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform' xmlns="http://tempuri.org/">
    <xsl:output encoding='UTF-8' indent='yes' method='xml'/>
    <!-- copy everything into the output -->
    <xsl:template match='@*|node()'>
        <xsl:copy>
            <xsl:apply-templates select='@*|node()'/>
        </xsl:copy>
    </xsl:template>
    <!-- change the namespace declaration for level2 -->
    <xsl:template match="level2">
        <level2 xmlns='http://tempuri.org/'>
            <xsl:copy-of select="@*|node()"/>
        </level2>
    </xsl:template>
</xsl:stylesheet>

Upvotes: 0

Views: 592

Answers (1)

michael.hor257k
michael.hor257k

Reputation: 117115

to get rid of the empty xmlns or changing it to the proper namespace.

There is no way to "get rid of the empty xmlns" other than moving the elements in no-namespace to the same namespace as their parent/ancestor element:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<!-- identity transform -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="*[not(namespace-uri(.))]">
    <xsl:element name="{local-name()}" namespace="http://tempuri.org/">
        <xsl:apply-templates select="@*|node()"/>
    </xsl:element>
</xsl:template>

</xsl:stylesheet>

Alternatively, you could move ALL elements to no-namespace:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="*">
    <xsl:element name="{local-name()}">
        <xsl:copy-of select="@*"/>
        <xsl:apply-templates/>
    </xsl:element>
</xsl:template>

</xsl:stylesheet>

However, both of these solutions are flawed; one has to assume that the namespaces are there for a good reason. Getting rid of the difference between <elem xmlns="http://tempuri.org/"> and just <elem> may produce unexpected results.

Upvotes: 1

Related Questions