F khader
F khader

Reputation: 45

How to remove xml namespace aliases by using XSLT

I was trying to convert the below xml that has xml namespace aliases on all tags.

Input:

<?xml version="1.0" encoding="UTF-8"?>
<ns1:Header xmlns:ns1="abc.com">
    <ns1:Child1>
        <ns1:Child11>a</ns1:Child11>
        <ns1:Child12>b</ns1:Child12>
        <ns1:Child13>
            <ns1:Picks>
                <ns1:pick1>1</ns1:pick1>
                <ns1:pick2>2</ns1:pick2>
            </ns1:Picks>
        </ns1:Child13>
    </ns1:Child1>
</ns1:Header>

Desired Output:

<?xml version="1.0" encoding="UTF-8"?>
<Header xmlns:ns1="abc.com">
    <Child1>
        <Child11>a</Child11>
        <Child12>b</Child12>
        <Child13>
            <Picks>
                <pick1>1</pick1>
                <pick2>2</pick2>
            </Picks>
        </Child13>
    </Child1>
</Header>

Is there any easier out of the box XSLT ways to accomplish this?

Upvotes: 1

Views: 484

Answers (1)

zx485
zx485

Reputation: 29022

If I interpret your question correctly, you want to change the namespaces of the child elements of Header.
This can be achieved with the following templates:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns1="abc.com" >
<xsl:output method="xml" indent="yes"/>

  <xsl:template match="*">                <!-- Removes all ns1 namespaces from the child elements -->
    <xsl:element name="{local-name()}">
        <xsl:apply-templates select="node()|@*" />
    </xsl:element>
  </xsl:template>

  <xsl:template match="ns1:Header">       <!-- Removes the ns1 namespace from the Header element but keeps an xmlns:ns1 definition -->
    <Header xmlns:ns1="abc.com">
        <xsl:apply-templates select="node()|@*" />
    </Header>
  </xsl:template>

</xsl:stylesheet>

Its output is:

<?xml version="1.0"?>
<Header xmlns:ns1="abc.com">
    <Child1>
        <Child11>a</Child11>
        <Child12>b</Child12>
        <Child13>
            <Picks>
                <pick1>1</pick1>
                <pick2>2</pick2>
            </Picks>
        </Child13>
    </Child1>
</Header>

If necessary, add an identity template to copy missing elements.


If you want to change the default namespace of all elements instead, this would simplify things to this one template:

<xsl:template match="*">             <!-- Changes the default namespaces of all elements -->
  <xsl:element name="{local-name()}" namespace="abc.com">
    <xsl:apply-templates select="node()|@*" />
  </xsl:element>
</xsl:template>

In this case the output would be:

<?xml version="1.0"?>
<Header xmlns="abc.com">
    <Child1>
        <Child11>a</Child11>
        <Child12>b</Child12>
        <Child13>
            <Picks>
                <pick1>1</pick1>
                <pick2>2</pick2>
            </Picks>
        </Child13>
    </Child1>
</Header>

Upvotes: 2

Related Questions