Java lib or app to convert CSV to XML file? [closed]
As the others above, I don't know any one-step way to do that, but if you are ready to use very simple external libraries, I would suggest:
OpenCsv for parsing CSV (small, simple, reliable and easy to use)
Xstream to parse/serialize XML (very very easy to use, and creating fully human readable xml)
Using the same sample data as above, code would look like:
package fr.megiste.test;import java.io.FileReader;import java.io.FileWriter;import java.util.ArrayList;import java.util.List;import au.com.bytecode.opencsv.CSVReader;import com.thoughtworks.xstream.XStream;public class CsvToXml { public static void main(String[] args) { String startFile = "./startData.csv"; String outFile = "./outData.xml"; try { CSVReader reader = new CSVReader(new FileReader(startFile)); String[] line = null; String[] header = reader.readNext(); List out = new ArrayList(); while((line = reader.readNext())!=null){ List<String[]> item = new ArrayList<String[]>(); for (int i = 0; i < header.length; i++) { String[] keyVal = new String[2]; String string = header[i]; String val = line[i]; keyVal[0] = string; keyVal[1] = val; item.add(keyVal); } out.add(item); } XStream xstream = new XStream(); xstream.toXML(out, new FileWriter(outFile,false)); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } }}
Producing the following result:(Xstream allows very fine tuning of the result...)
<list> <list> <string-array> <string>string</string> <string>hello world</string> </string-array> <string-array> <string>float1</string> <string>1.0</string> </string-array> <string-array> <string>float2</string> <string>3.3</string> </string-array> <string-array> <string>integer</string> <string>4</string> </string-array> </list> <list> <string-array> <string>string</string> <string>goodbye world</string> </string-array> <string-array> <string>float1</string> <string>1e9</string> </string-array> <string-array> <string>float2</string> <string>-3.3</string> </string-array> <string-array> <string>integer</string> <string>45</string> </string-array> </list> <list> <string-array> <string>string</string> <string>hello again</string> </string-array> <string-array> <string>float1</string> <string>-1</string> </string-array> <string-array> <string>float2</string> <string>23.33</string> </string-array> <string-array> <string>integer</string> <string>456</string> </string-array> </list> <list> <string-array> <string>string</string> <string>hello world 3</string> </string-array> <string-array> <string>float1</string> <string>1.40</string> </string-array> <string-array> <string>float2</string> <string>34.83</string> </string-array> <string-array> <string>integer</string> <string>4999</string> </string-array> </list> <list> <string-array> <string>string</string> <string>hello 2 world</string> </string-array> <string-array> <string>float1</string> <string>9981.05</string> </string-array> <string-array> <string>float2</string> <string>43.33</string> </string-array> <string-array> <string>integer</string> <string>444</string> </string-array> </list></list>
I know you asked for Java, but this strikes me as a task well suited to a scripting language. Here is a quick (very simple) solution written in Groovy.
test.csv
string,float1,float2,integerhello world,1.0,3.3,4goodbye world,1e9,-3.3,45hello again,-1,23.33,456hello world 3,1.40,34.83,4999hello 2 world,9981.05,43.33,444
csvtoxml.groovy
#!/usr/bin/env groovydef csvdata = []new File("test.csv").eachLine { line -> csvdata << line.split(',')}def headers = csvdata[0]def dataRows = csvdata[1..-1]def xml = new groovy.xml.MarkupBuilder()// write 'root' elementxml.root { dataRows.eachWithIndex { dataRow, index -> // write 'entry' element with 'id' attribute entry(id:index+1) { headers.eachWithIndex { heading, i -> // write each heading with associated content "${heading}"(dataRow[i]) } } }}
Writes the following XML to stdout:
<root> <entry id='1'> <string>hello world</string> <float1>1.0</float1> <float2>3.3</float2> <integer>4</integer> </entry> <entry id='2'> <string>goodbye world</string> <float1>1e9</float1> <float2>-3.3</float2> <integer>45</integer> </entry> <entry id='3'> <string>hello again</string> <float1>-1</float1> <float2>23.33</float2> <integer>456</integer> </entry> <entry id='4'> <string>hello world 3</string> <float1>1.40</float1> <float2>34.83</float2> <integer>4999</integer> </entry> <entry id='5'> <string>hello 2 world</string> <float1>9981.05</float1> <float2>43.33</float2> <integer>444</integer> </entry></root>
However, the code does very simple parsing (not taking into account quoted or escaped commas) and it does not account for possible absent data.