omer khalid
omer khalid

Reputation: 895

How to remove namespaces from input XML in XSLT 2.0 using <xsl:copy-of>?

I am trying to use the xsl:copy-of function to copy one node from the input XML to the output XML. I am using the copy-namespaces="no" mode to avoid copying the input namespaces. But there is still a default namespace being copied in the product tag as xmlns="".

My question is:
How can I use the xsl:copy-of function to remove these default namespaces? And also, how can I remove the namespaces from the child nodes as well.

Input XML:

<?xml version="1.0" encoding="UTF-8"?>
<ns:result xmlns:ns="http://example.com">
   <product ku="00001">
      <ku>00001</ku>
      <custom-attributes>
         <custom-attribute xmlns:dt="http://example.com-dt" dt:dt="string" name="Instrument" />
      </custom-attributes>
   </product>
   <product ku="00002">
      <ku>00002</ku>
      <custom-attributes>
         <custom-attribute xmlns:dt="http://example.com-dt" dt:dt="string" name="Instrument">
            <value>112</value>
         </custom-attribute>
      </custom-attributes>
   </product>
</ns:result>

XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  xmlns:t="http://test.com/dataservice/dop" xmlns:fc="http://example.com" exclude-result-prefixes="t fc ">
    <xsl:output indent="yes" encoding="UTF-8"/>
    <xsl:template match="*">
        <final xmlns="http://www.example.com/ns/core/tetrex"
            xmlns:dt="http://www.example.com/ns/core/tetrex-dt"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" branch="enterprise" build="4.0.5"
            family="fine" major="6" minor="1"
            xsi:schemaLocation="http://www.example-dt.com dt.xsd">
            <xsl:for-each select="//fc:result/product">
                <xsl:copy-of select="current()" copy-namespaces="no"  />
            </xsl:for-each>
        </final>
    </xsl:template>
</xsl:stylesheet>

Current Output XML:

<?xml version="1.0" encoding="UTF-8"?>
<final xmlns="http://www.example.com/ns/core/tetrex"
       xmlns:dt="http://www.example.com/ns/core/tetrex-dt"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       branch="enterprise"
       build="4.0.5"
       family="fine"
       major="6"
       minor="1"
       xsi:schemaLocation="http://www.example-dt.com dt.xsd">
   <product xmlns="" ku="00001">
      <ku>00001</ku>
      <custom-attributes>
         <custom-attribute xmlns:dt="http://example.com-dt" dt:dt="string" name="Instrument"/>
      </custom-attributes>
   </product>
   <product xmlns="" ku="00002">
      <ku>00002</ku>
      <custom-attributes>
         <custom-attribute xmlns:dt="http://example.com-dt" dt:dt="string" name="Instrument">
            <value>112</value>
         </custom-attribute>
      </custom-attributes>
   </product>
</final>

Desired Output:

<?xml version="1.0" encoding="UTF-8"?>
<final xmlns="http://www.example.com/ns/core/tetrex"
       xmlns:dt="http://www.example.com/ns/core/tetrex-dt"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       branch="enterprise"
       build="4.0.5"
       family="fine"
       major="6"
       minor="1"
       xsi:schemaLocation="http://www.example-dt.com dt.xsd">
   <product ku="00001">
      <ku>00001</ku>
      <custom-attributes>
         <custom-attribute dt:dt="string" name="Instrument"/>
      </custom-attributes>
   </product>
   <product ku="00002">
      <ku>00002</ku>
      <custom-attributes>
         <custom-attribute dt:dt="string" name="Instrument">
            <value>112</value>
         </custom-attribute>
      </custom-attributes>
   </product>
</final>

Upvotes: 0

Views: 595

Answers (1)

michael.hor257k
michael.hor257k

Reputation: 116959

The output you show can be obtained by applying the following stylesheet:

XSLT 2.0

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  
xpath-default-namespace="http://example.com"
xmlns="http://www.example.com/ns/core/tetrex"
xmlns:dt="http://example.com-dt"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>

<xsl:template match="/result">
    <final
        branch="enterprise" 
        build="4.0.5"
        family="fine" 
        major="6" 
        minor="1"
        xsi:schemaLocation="http://www.example-dt.com dt.xsd">
        <xsl:apply-templates/>
    </final>
</xsl:template>

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

</xsl:stylesheet>

Note that this does NOT "remove namespaces from input XML". On the contrary: it takes elements that were in no-namespace in the input XML and places them in the http://www.example.com/ns/core/tetrex namespace that is the default namespace for the output XML.


Demo: https://xsltfiddle.liberty-development.net/ehW12fF

Upvotes: 1

Related Questions