Search code examples
xmlxsltnamespacesprefix

Add Namespace Prefix To root node


I need to change the namespace of the root node and add the namespace prefix to only root element not for child elements.

I have following XML:

<?xml version="1.0" encoding="UTF-8"?> 
<Class xmlns="https://api.ladbrokes.com/v1/sportsbook-couchbase/SportsbookCouchbase.xsd">
<blurb >Test</blurb>
<channels >
<e >I</e>
<e >J</e>
<e >K</e>
</channels>
<classSortCode >Test</classSortCode>
<classStatus >Test</classStatus>
<creationDateTime >2013-03-21T22:29:01.58+05:30</creationDateTime>
<isActive >true</isActive>
<lastUpdatedDateTime >2013-03-21T22:29:01.58+05:30</lastUpdatedDateTime>
<locale >Test</locale>
</Class>

And I need this to become

<?xml version="1.0" encoding="UTF-8"?> 
<ns0:Class xmlns:ns0="https://api.ladbrokes.com/v1/sportsbook-couchbase/Temp.xsd">
<blurb >Test</blurb>
<channels >
<e >I</e>
<e >J</e>
<e >K</e>
</channels>
<classSortCode >Test</classSortCode>
<classStatus >Test</classStatus>
<creationDateTime >2013-03-21T22:29:01.58+05:30</creationDateTime>
<isActive >true</isActive>
<lastUpdatedDateTime >2013-03-21T22:29:01.58+05:30</lastUpdatedDateTime>
<locale >Test</locale>
</ns0:Class>

Can i achieve this using XSLT? Kindly assist me in this regard.

Thanks, Siva


Solution

  • This is how you can give the document element a different namespace and move all of the other elements into the null namespace:

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                    xmlns:ns0="https://api.ladbrokes.com/v1/sportsbook-couchbase/Temp.xsd">
      <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
    
      <xsl:template match="@* | node()">
        <xsl:copy>
          <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
      </xsl:template>
    
      <xsl:template match="/*">
        <xsl:element name="ns0:{local-name()}">
          <xsl:apply-templates select="@* | node()" />
        </xsl:element>
      </xsl:template>
    
      <xsl:template match="*/*">
        <xsl:element name="{local-name()}">
          <xsl:apply-templates select="@* | node()" />
        </xsl:element>
      </xsl:template>
    </xsl:stylesheet>
    

    When run on your sample input, the result is:

    <ns0:Class xmlns:ns0="https://api.ladbrokes.com/v1/sportsbook-couchbase/Temp.xsd">
      <blurb>Test</blurb>
      <channels>
        <e>I</e>
        <e>J</e>
        <e>K</e>
      </channels>
      <classSortCode>Test</classSortCode>
      <classStatus>Test</classStatus>
      <creationDateTime>2013-03-21T22:29:01.58+05:30</creationDateTime>
      <isActive>true</isActive>
      <lastUpdatedDateTime>2013-03-21T22:29:01.58+05:30</lastUpdatedDateTime>
      <locale>Test</locale>
    </ns0:Class>
    

    For clarification, this is how you can change the namespace for the document element and leave everything else in the namespace they already had.

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                    xmlns:ns0="https://api.ladbrokes.com/v1/sportsbook-couchbase/Temp.xsd">
      <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
    
      <xsl:template match="@* | node()">
        <xsl:copy>
          <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
      </xsl:template>
    
      <xsl:template match="/*">
        <xsl:element name="ns0:{local-name()}">
          <xsl:copy-of select="namespace::*" />
          <xsl:apply-templates select="@* | node()" />
        </xsl:element>
      </xsl:template>
    </xsl:stylesheet>
    

    And this is the result from that. Note the small but critical difference in the namespace declarations at the top:

    <ns0:Class xmlns:ns0="https://api.ladbrokes.com/v1/sportsbook-couchbase/Temp.xsd" 
         xmlns="https://api.ladbrokes.com/v1/sportsbook-couchbase/SportsbookCouchbase.xsd">
      <blurb>Test</blurb>
      <channels>
        <e>I</e>
        <e>J</e>
        <e>K</e>
      </channels>
      <classSortCode>Test</classSortCode>
      <classStatus>Test</classStatus>
      <creationDateTime>2013-03-21T22:29:01.58+05:30</creationDateTime>
      <isActive>true</isActive>
      <lastUpdatedDateTime>2013-03-21T22:29:01.58+05:30</lastUpdatedDateTime>
      <locale>Test</locale>
    </ns0:Class>