Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java - Generate XML from another XML + XSD

Tags:

xml

xslt

xsd

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!

like image 651
Alex Avatar asked Sep 18 '26 16:09

Alex


1 Answers

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>
like image 161
Dimitre Novatchev Avatar answered Sep 21 '26 08:09

Dimitre Novatchev



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!