Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to replace namespace prefix in element and attributes using xslt

I have a source xml like following:

<SampleRequest xmlns="http://sample.com/s"
       xmlns:s1="http://sample.com/s1"
       xmlns:s2="http://sample.com/s2"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://sample.com/s schema.xsd">
<data>
<s1:customer s1:firstName="Jim" s1:lastName="Ellison"/>
<s2:address>
    123 test street
</s2:address>
</data>
</SampleRequest>

I need to transform it to the following

<SampleRequest xmlns="http://sample.com/t"
       xmlns:t1="http://sample.com/t1"
       xmlns:t2="http://sample.com/t2"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://sample.com/t targetSchema.xsd">
<data>
<t1:customer t1:firstName="Jim" t1:lastName="Ellison"/>
<t2:address>
    123 test street
</t2:address>
</data>
</SampleRequest>

both xmls has identical schema but different namespace.

I was trying to use following xslt

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
            xmlns="http://sample.com/s"
            xmlns:s1="http://sample.com/s1"
            xmlns:s2="http://sample.com/s2"
            xmlns:t1="http://sample.com/t1"
            xmlns:t2="http://sample.com/t2"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="s1 s2">
<xsl:output method="xml" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
    <SampleRequest xmlns="http://sample.com/t"
       xmlns:t1="http://sample.com/t1"
       xmlns:t2="http://sample.com/t2"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <xsl:attribute name="xsi:schemaLocation" namespace="http://www.w3.org/2001/XMLSchema-instance">
            http://sample.com/t targetSchema.xsd
        </xsl:attribute>
        <xsl:copy>
             <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </SampleRequest>
</xsl:template>
<xsl:template match="s1:*"> 
    <xsl:element name="t1:{local-name()}" namespace="http://sample.com/t1">      
        <xsl:apply-templates select="* | node()"/>
    </xsl:element>
</xsl:template>

<xsl:template match="s2:*"> 
    <xsl:element name="t2:{local-name()}" namespace="http://sample.com/t2">
        <xsl:apply-templates select="* | node()"/>
    </xsl:element>
</xsl:template>
</xsl:stylesheet>

And I am getting following result

<?xml version="1.0" encoding="UTF-8"?><SampleRequest xmlns="http://sample.com/t"   xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:t2="http://sample.com/t2" xmlns:t1="http://sample.com/t1" xsi:schemaLocation=" http://sample.com/t targetSchema.xsd">
<t1:customer/>
<t2:address>
    123 test street
</t2:address>
</SampleRequest>

It seems all attributes are missing. I am very new to XSLT, every bit help appreciated

like image 634
user1329164 Avatar asked Nov 19 '25 03:11

user1329164


1 Answers

There are two problems in your XSLT. Firstly, where you match the s1 and s2 elements, you are not subsequently trying to apply templates to any attributes. You need to replace this statement

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

With this statement

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

Secondly, you don't have any templates to match such attributes. You need a template like so:

<xsl:template match="@s1:*">
    <xsl:attribute name="t1:{local-name()}">
        <xsl:value-of select="." />
    </xsl:attribute>
</xsl:template>

Try this XSLT

<xsl:stylesheet version="1.0" 
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
   xmlns="http://sample.com/s" 
   xmlns:s1="http://sample.com/s1" 
   xmlns:s2="http://sample.com/s2" 
   xmlns:t1="http://sample.com/t1" 
   xmlns:t2="http://sample.com/t2" 
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
   xmlns:xs="http://www.w3.org/2001/XMLSchema" 
   exclude-result-prefixes="s1 s2">

   <xsl:output method="xml" encoding="UTF-8" indent="yes"/>

   <xsl:strip-space elements="*"/>

   <xsl:template match="/">
      <SampleRequest 
        xmlns="http://sample.com/t" 
        xmlns:t1="http://sample.com/t1" 
        xmlns:t2="http://sample.com/t2" 
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
         <xsl:attribute name="xsi:schemaLocation">http://sample.com/t targetSchema.xsd</xsl:attribute>
         <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
         </xsl:copy>
      </SampleRequest>
   </xsl:template>

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

   <xsl:template match="@s1:*">
      <xsl:attribute name="t1:{local-name()}">
         <xsl:value-of select="."/>
      </xsl:attribute>
   </xsl:template>

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

   <xsl:template match="@s2:*">
      <xsl:attribute name="t2:{local-name()}">
         <xsl:value-of select="."/>
      </xsl:attribute>
   </xsl:template>
</xsl:stylesheet>

When applied to your sample XML, the following is output:

<SampleRequest 
   xsi:schemaLocation="http://sample.com/t targetSchema.xsd" 
   xmlns:t1="http://sample.com/t1" 
   xmlns:t2="http://sample.com/t2" 
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
   xmlns:xs="http://www.w3.org/2001/XMLSchema" 
   xmlns="http://sample.com/t">
   <t1:customer t1:firstName="Jim" t1:lastName="Ellison"/>
   <t2:address> 123 test street </t2:address>
</SampleRequest>
like image 107
Tim C Avatar answered Nov 22 '25 03:11

Tim C



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!