user1761848
user1761848

Reputation: 95

How to add namespace and prefix for all elements and attributes using XSLT?

My problem is how to add namespace and prefix for all elements and attributes using XSLT? My input xml as is....

<ProcessCreditMemo xmlns='CreditMemo' 
                   xmlns:xsd='http://www.w3.org/2001/XMLSchema' 
                   xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
                   xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'>
<ORDER_HEADERDetails>
    <ORDER_HEADER>
    <NAME>0010185214</NAME>

to be...

<ns0:ProcessCreditMemo xmlns='CreditMemo' 
                       xmlns:xsd='http://www.w3.org/2001/XMLSchema' 
                       xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
                       xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/' 
                       xmlns:ns0="http://tempuri.org/">
<ns0:ORDER_HEADERDetails>
    <ns0:ORDER_HEADER>
   <ns0:NAME>0010185214</NAME>

I need add the prefix "ns0:" for all elements and attributes, and add the namespace "xmlns:ns0="http://tempuri.org/" in the header "ProcessCreditMemo".

I am trying to build a XSLT to do it...

<xsl:stylesheet version="1.0" 
          xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<xsl:output method="xml" encoding="UTF-8" indent="yes"/>
<xsl:template match="node()|text()|@*">
    <xsl:copy>
        <xsl:if test="local-name()='ProcessCreditMemo'">
            <xsl:attribute name="xmlns" namespace="http://tempuri.org/" />
        </xsl:if>

but the resulting XML duplicates the prefix with empty value.

<ProcessCreditMemo xmlns="CreditMemo" 
                   xmlns:ns0="http://tempuri.org/" 
                   xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
                   xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
                   ns0:xmlns="">

Upvotes: 8

Views: 16506

Answers (1)

Dimitre Novatchev
Dimitre Novatchev

Reputation: 243479

This transformation:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:ns0="http://tempuri.org/">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

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

 <xsl:template match="*">
  <xsl:element name="ns0:{name()}" namespace="http://tempuri.org/">
   <xsl:copy-of select="namespace::*"/>
       <xsl:apply-templates select="node()|@*"/>
  </xsl:element>
 </xsl:template>
</xsl:stylesheet>

when applied on the (corrected) provided input (severely malformed, incomplete XML):

<ProcessCreditMemo xmlns='CreditMemo'
  xmlns:xsd='http://www.w3.org/2001/XMLSchema'
  xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
  xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'>
  <ORDER_HEADERDetails>
    <ORDER_HEADER>
      <NAME>0010185214</NAME>
    </ORDER_HEADER>
  </ORDER_HEADERDetails>
</ProcessCreditMemo>

produces the wanted, correct result (not the severely malformed/incomplete provided wanted-result):

<ns0:ProcessCreditMemo xmlns:ns0="http://tempuri.org/" xmlns="CreditMemo" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
   <ns0:ORDER_HEADERDetails>
      <ns0:ORDER_HEADER>
         <ns0:NAME>0010185214</ns0:NAME>
      </ns0:ORDER_HEADER>
   </ns0:ORDER_HEADERDetails>
</ns0:ProcessCreditMemo>

Upvotes: 14

Related Questions