3

I have an issue with generating a XML file from another XML file. My use case is this:

  1. I have a XML file with the following format:

    <tag1>
        <tag2>value2</tag2>
        <tag3>value3_1, value3_2, value3_3</tag3>
        <tag4>
           <tag4_1>value4_1</tag4_1>
           <tag4_2>value4_2</tag4_2>
        </tag4>
    </tag1>
    

Yeah, I know it's pretty messy but that's the way I got it.

  1. I also have an XSD schema which I use to generate corresponding Java classes using JAXB (this works OK).

What I need now is a way to create another XML file from the original one, having this format:

<element name="tag1.tag2">
     <value>value2</value>
</element>
<element name="tag1.tag3">
     <value>value3_1, value3_2, value3_3</value>
</element>
<element name="tag1.tag4.tag4_1"> 
     <value>value4_1</value>
</element>
<element name="tag1.tag4.tag4_2"> 
     <value>value4_2</value>
</element>

Do you have any suggestions regarding what framework/libraries I should use to achieve this without doing my own parsing/creating mechanism?

I was thinking of using XSLT but I don't have any experience with it...

Thanks!

2
  • 1
    How is XSD relevant here? i see transforming xml from 1 format to another...job of XSLT Commented Feb 8, 2012 at 15:35
  • We are generating the first XML in this example from an XSD using JAXB. Commented Feb 9, 2012 at 9:55

1 Answer 1

5

This transformation:

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

 <xsl:template match="*[not(*)]">
  <xsl:variable name="vName">
   <xsl:for-each select="ancestor-or-self::*">
    <xsl:if test="not(position() = 1)">.</xsl:if>
    <xsl:value-of select="name()"/>
   </xsl:for-each>
  </xsl:variable>

  <element name="{$vName}">
   <value><xsl:value-of select="."/></value>
  </element>
 </xsl:template>
</xsl:stylesheet>

when applied on the provided XML document:

<tag1>
    <tag2>value2</tag2>
    <tag3>value3_1, value3_2, value3_3</tag3>
    <tag4>
        <tag4_1>value4_1</tag4_1>
        <tag4_2>value4_2</tag4_2>
    </tag4>
</tag1>

produces the wanted, correct result:

<element name="tag1.tag2">
   <value>value2</value>
</element>
<element name="tag1.tag3">
   <value>value3_1, value3_2, value3_3</value>
</element>
<element name="tag1.tag4.tag4_1">
   <value>value4_1</value>
</element>
<element name="tag1.tag4.tag4_2">
   <value>value4_2</value>
</element>
Sign up to request clarification or add additional context in comments.

2 Comments

Great answer, thanks! It works like a charm :) I had some more details to the problem, but by adapting the transformation you provided I managed to have a working solution to my problem.
Awesome logic .. !! :D thumbs-up! :)

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.