0

My input xml looks like this as given below

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<L1>
    <L2>
        <l3>
            <item>
                <State>1</state>
                <currency>
                    <value1 xmlns:xs="www.anotherexample.com">5</value1>
                    <value2 xmlns:xs="www.anotherexample.com">dd</value2>
                </currency>
            </item>
            <item2>
                <a>1</a>
                <b>2</b>
                <c>3</c>
             </item2>
             <item3>
                 <e>2</e>
                 <l>3</l>
                 <m>3</m>
            </item3>
            <item4>
                 <n>r</n>
                 <p>5</p>
            </item4>
        </l3>
     </L2>
</L1>

i have two requirements

1) the xml has to be added with an envelope ie another xml will sit on top of this whole xml and resultant should look like

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>

    <start>
       <a></a>
        .....
        ..... 
       <Body>
       <Envelope>
           <L1>
               <L2>
                   <l3>
                       <item>
                           <State>1</state>
                           <currency>
                               <value1 xmlns:xs="www.anotherexample.com">5</value1>
                               <value2 xmlns:xs="www.anotherexample.com">ca</value2>
                            </currency>
                        </item>
                        <item2>
                              <a>1</a>
                              <b>2</b>
                              <c>3</c>
                         </item2>
                         <item3>
                              <e>2</e>
                              <l>3</l>
                               <m>3</m>
                          </item3>
                          <item4>
                               <n>r</n>
                               <p>5</p>
                          </item4>
                    </l3>
                </L2>
             </L1>
      </Envelope>   
      </Body>
       .....
       ..... 
    </start> 

2 the second requirment is that the root tag of the original xml ie the L1 tag should have a namespace added to it so the root tag becomes

    <start>
       <a></a>
        .....
        ..... 
       <Body>
           <Envelope>    
              <L1 xmlns="www.example.com">
                  <L2>
                     <l3>
                        <item>
                           <State>1</state>
                           <currency>
                                 <value1  xmlns:xs="www.anotherexample.com">5</value1>
                                 <value2   xmlns:xs="www.anotherexample.com">ca</value2>
                            </currency>
                </item>
                        <item2>
                             <a>1</a>
                             <c>3</c>
                        </item2>
                        <item3>
                             <e>2</e>
                        </item3>
                        <item4>
                            <n>r</n>
                        </item4>
                   </l3>
                </L2>
             </L1>
        </Envelope>
      </Body>
    </start>

how do we design an xslt to do this combination of transformation. i have searched and found solutions for adding namespace to the root tag, but how can i achieve both the results simulataneously

note: There are many elements inside the input xml that will be ignored or processed by using call template, so directly copying the xml and adding namespace fails in this case

example: i may be wanting only 1 tag from the input in the output xml. Edited the original post to show that the original input xml is not intended to be copied as it is to the output , as shown in the new output, the output xml will be in variation with the input XML with several tags missing and the order of the tags have to be constant Sorry for the incomplete description previously

4
  • Surely that's not your input XML? It is not valid on several counts. Commented May 5, 2014 at 20:42
  • yes michael, this is not my input xml, just a small part of the main thing i wanted to get done Commented May 5, 2014 at 21:30
  • "the output xml will be in variation with the input XML with several tags missing or some manipulation done on them" It is not possible to answer this part of your question, because it's too vague. In general, you need to decide if you want your stylesheet to specify (a) the elements to include in the output or (b) the elements to exclude. As for doing "some manipulation on them" you will need "some code" to accomplish that... Commented May 5, 2014 at 22:52
  • If we remove the manipulation part from consideration, is it possible to leave aside some of the nodes,like we see item2, item3, item4 and keep to the need by xslt . I have edited the question to make this specific Commented May 5, 2014 at 23:00

1 Answer 1

1

the second requirment is that the root tag of the original xml ie the L1 tag should have a namespace added to it

That's not an accurate description of what you show as your output: all the elements that are descendants of the root inherit the root's namespace - therefore you need to add the new namespace to each and every one of them:

XSLT 1.0

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="/">
    <start>
        <a></a>
        <!-- ... -->
        <Body>
            <Envelope> 
                <xsl:apply-templates select="*" />
            </Envelope>
        </Body>
    </start>
</xsl:template>

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

<xsl:template match="@*">
    <xsl:copy/>
</xsl:template>

</xsl:stylesheet>

when the above stylesheet is applied to the corrected input of:

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> 
<L1>
  <L2>
    <l3>
      <item>
        <state>1</state>
        <currency>LEVEL</currency> 
            <value1 xmlns:xsi="http://www.w3.org/2001/XMLSchema" xsi:type="xs:int">5</value1>
            <value2 xmlns:xsi="http://www.w3.org/2001/XMLSchema" xsi:type="xs:int">ca</value2>
      </item>
    </l3>
  </L2>
</L1>

the result is:

<?xml version="1.0" encoding="UTF-8"?>
<start>
   <a/>
   <Body>
      <Envelope>
         <L1 xmlns="www.example.com">
            <L2>
               <l3>
                  <item>
                     <state>1</state>
                     <currency>LEVEL</currency>
                     <value1 xmlns:xsi="http://www.w3.org/2001/XMLSchema" xsi:type="xs:int">5</value1>
                     <value2 xmlns:xsi="http://www.w3.org/2001/XMLSchema" xsi:type="xs:int">ca</value2>
                  </item>
               </l3>
            </L2>
         </L1>
      </Envelope>
   </Body>
</start>

Edit

If you want to remove some nodes from the output, create a specific template for them and leave it empty. For example, using the following input:

<L1>
    <L2>
        <l3>
            <item>
                <state>1</state>
                <currency>
                    <value1 xmlns:xsi="http://www.w3.org/2001/XMLSchema" xsi:type="xs:int">5</value1>
                    <value2 xmlns:xsi="http://www.w3.org/2001/XMLSchema" xsi:type="xs:int">ca</value2>
                </currency>
            </item>
            <item2>
                <a>1</a>
                <b>2</b>
                <c>3</c>
             </item2>
             <item3>
                 <e>2</e>
                 <l>3</l>
                 <m>3</m>
            </item3>
            <item4>
                 <n>r</n>
                 <p>5</p>
            </item4>
        </l3>
     </L2>
</L1>

we will add an empty template for elements <b, <l>, <m> and <p> to our previous stylesheet:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="/">
    <start>
        <a></a>
        <!-- ... -->
        <Body>
            <Envelope> 
                <xsl:apply-templates select="*" />
            </Envelope>
        </Body>
    </start>
</xsl:template>

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

<xsl:template match="@*">
    <xsl:copy/>
</xsl:template>

<xsl:template match="b|l|m|p"/>

</xsl:stylesheet>

and obtain the following result:

<?xml version="1.0" encoding="UTF-8"?>
<start>
   <a/>
   <Body>
      <Envelope>
         <L1 xmlns="www.example.com">
            <L2>
               <l3>
                  <item>
                     <state>1</state>
                     <currency>
                        <value1 xmlns:xsi="http://www.w3.org/2001/XMLSchema" xsi:type="xs:int">5</value1>
                        <value2 xmlns:xsi="http://www.w3.org/2001/XMLSchema" xsi:type="xs:int">ca</value2>
                     </currency>
                  </item>
                  <item2>
                     <a>1</a>
                     <c>3</c>
                  </item2>
                  <item3>
                     <e>2</e>
                  </item3>
                  <item4>
                     <n>r</n>
                  </item4>
               </l3>
            </L2>
         </L1>
      </Envelope>
   </Body>
</start>
Sign up to request clarification or add additional context in comments.

8 Comments

hi michael, this does add namespace to my intial xml but i have problem. In the big xml that i have i will be selecting only few values from each of the child nodes of the input xml. this i thought of establishing by using call templates inside the first template match = /, but that results in repetition of the elements. any idea to get around this problem
@user2873194 I suggest you post a complete question: show the entire input XML and explain exactly how you want to modify it. I also don't see what "call templates" has to do with any of this.
@michaelhor257k. i have edited the question and hope that makes the use of the question clear
@michaelhor257k. thanks for the answer, your answer showed me the way
The above transform doesnot preserve my namespace in value 1
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.