Search code examples
xmlxsltnamespacestransformationprefix

Add prefix NS0 only in the root node


Hy Guys,

Please, help me! I need include the namespace prefix only in the first node of XML, the other nodes must be without prefix and namespace. See the example below.

Before:

<RootNode xmlns="https://xxx/yyy/v1">
<CreatedBy>admin</CreatedBy>
<Task>
<Number>1</Number>
<Status>-1</Status>
<Name>Fechada</Name>
</Task>
</RootNode>

After:

<ns0:RootNode xmlns:ns0="https://xxx/yyy/v1">
<CreatedBy>admin</CreatedBy>
<Task>
<Number>1</Number>
<Status>-1</Status>
<Name>Fechada</Name>
</Task>
</ns0:RootNode>

How can I do this using XSL?


Solution

  • You have two things you want to do here.

    1) Add a namespace prefix to the root element. This can be done with the following template

    <xsl:template match="/*">
      <xsl:element name="ns0:{local-name()}" namespace="{namespace-uri()}">
        <xsl:apply-templates select="@*|node()" />
      </xsl:element>
    </xsl:template>
    

    2) For all other elements, create elements with the same name but in no namespace. This can be done with the following

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

    Putting this all together, with the identity template to handle everything else, gives you the following XSLT

    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
      <xsl:output method="html" indent="yes" html-version="5"/>
    
      <xsl:template match="@*|node()">
        <xsl:copy>
          <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
      </xsl:template>
    
      <xsl:template match="/*">
        <xsl:element name="ns0:{local-name()}" namespace="{namespace-uri()}">
          <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>