Java库或应用程序将CSV转换为XML文件?
是否有一个现有的应用程序或库中的Java允许我将CSV
数据文件转换为XML
文件?
XML
标签将通过可能包含列标题的第一行来提供。
也许这可能有帮助: JSefa
您可以使用此工具读取CSV文件并将其序列化为XML。
和其他人一样,我不知道有什么一步一步的办法,但是如果你准备使用非常简单的外部库,我会build议:
OpenCsvparsingCSV(小巧,简单,可靠和易于使用)
Xstreamparsing/序列化XML(非常容易使用,并创build完全人类可读的XML)
使用与上面相同的示例数据,代码如下所示:
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(); } } }
产生以下结果:(Xstream允许非常微调的结果…)
<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>
我知道你问了Java,但是这让我非常适合脚本语言。 这是一个用Groovy编写的快速(非常简单)的解决scheme。
test.csv
string,float1,float2,integer hello world,1.0,3.3,4 goodbye world,1e9,-3.3,45 hello again,-1,23.33,456 hello world 3,1.40,34.83,4999 hello 2 world,9981.05,43.33,444
csvtoxml.groovy
#!/usr/bin/env groovy def 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' element xml.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]) } } } }
将以下XML写入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>
但是,代码做了非常简单的parsing(不考虑引号或转义逗号),并没有考虑到可能缺less的数据。
一般来说,我有一个用于处理CSV和平面文件的开源框架。 也许值得一看: JFileHelpers 。
使用该工具包,您可以使用bean编写代码,如:
@FixedLengthRecord() public class Customer { @FieldFixedLength(4) public Integer custId; @FieldAlign(alignMode=AlignMode.Right) @FieldFixedLength(20) public String name; @FieldFixedLength(3) public Integer rating; @FieldTrim(trimMode=TrimMode.Right) @FieldFixedLength(10) @FieldConverter(converter = ConverterKind.Date, format = "dd-MM-yyyy") public Date addedDate; @FieldFixedLength(3) @FieldOptional public String stockSimbol; }
然后用下面的方法parsing你的文本文件:
FileHelperEngine<Customer> engine = new FileHelperEngine<Customer>(Customer.class); List<Customer> customers = new ArrayList<Customer>(); customers = engine.readResource( "/samples/customers-fixed.txt");
你将有一个parsing对象的集合。
希望有所帮助!
此解决scheme不需要任何CSV或XML库,我知道,它不处理任何非法字符和编码问题,但是您也可能对此感兴趣,前提是您的CSVinput不会违反上述规则。
注意:除非你知道自己做了什么,否则不应该使用这些代码(在某些官僚作品中可能会有这个机会)…在较老的运行环境中使用StringBuffer …
所以在这里我们去:
BufferedReader reader = new BufferedReader(new InputStreamReader( Csv2Xml.class.getResourceAsStream("test.csv"))); StringBuilder xml = new StringBuilder(); String lineBreak = System.getProperty("line.separator"); String line = null; List<String> headers = new ArrayList<String>(); boolean isHeader = true; int count = 0; int entryCount = 1; xml.append("<root>"); xml.append(lineBreak); while ((line = reader.readLine()) != null) { StringTokenizer tokenizer = new StringTokenizer(line, ","); if (isHeader) { isHeader = false; while (tokenizer.hasMoreTokens()) { headers.add(tokenizer.nextToken()); } } else { count = 0; xml.append("\t<entry id=\""); xml.append(entryCount); xml.append("\">"); xml.append(lineBreak); while (tokenizer.hasMoreTokens()) { xml.append("\t\t<"); xml.append(headers.get(count)); xml.append(">"); xml.append(tokenizer.nextToken()); xml.append("</"); xml.append(headers.get(count)); xml.append(">"); xml.append(lineBreak); count++; } xml.append("\t</entry>"); xml.append(lineBreak); entryCount++; } } xml.append("</root>"); System.out.println(xml.toString());
inputtest.csv(从本页另一个答案窃取):
string,float1,float2,integer hello world,1.0,3.3,4 goodbye world,1e9,-3.3,45 hello again,-1,23.33,456 hello world 3,1.40,34.83,4999 hello 2 world,9981.05,43.33,444
结果输出:
<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>
您可以使用Groovyexception简单地执行此操作,并且代码非常易读。
基本上,文本variables将被写入到contactData.csv
每行的contacts.xml
中,并且fields数组包含每一列。
def file1 = new File('c:\\temp\\ContactData.csv') def file2 = new File('c:\\temp\\contacts.xml') def reader = new FileReader(file1) def writer = new FileWriter(file2) reader.transformLine(writer) { line -> fields = line.split(',') text = """<CLIENTS> <firstname> ${fields[2]} </firstname> <surname> ${fields[1]} </surname> <email> ${fields[9]} </email> <employeenumber> password </employeenumber> <title> ${fields[4]} </title> <phone> ${fields[3]} </phone> </CLIENTS>""" }
最大的区别是JSefa引入的是,它可以将你的java对象序列化到CSV / XML / etc文件,并可以反序列化回java对象。 它是由注释驱动的,这使得你可以很好地控制输出。
JFileHelpers也看起来很有趣。
我不明白你为什么要这样做。 这听起来像货物崇拜编码。
将CSV文件转换为XML不会添加任何值。 你的程序已经在读取CSV文件了,所以争论说你需要XML不起作用。
另一方面,读取CSV文件,用这些值做一些事情 ,然后序列化到XML确实是有意义的(好,就像使用XML也是有道理的;)),但是你应该已经有了序列化为XML。
你可以使用XSLT 。 谷歌它,你会发现一些例子,如CSV到XML如果您使用XSLT ,然后可以将XML转换为任何您想要的格式。
Daniel Parker还有一个很好的图书馆ServingXML ,可以将几乎所有的纯文本格式转换成XML格式。
您的案例可以在这里find:它使用CSV文件中的字段标题作为XML元素名称。
没有任何我知道的,可以做到这一点,没有你至less写一点代码…你将需要2个独立的库:
- 一个CSVparsing器框架
- XML序列化框架
我build议的CSVparsing器(除非你想有一个有趣的编写自己的CSVparsing器)是OpenCSV(parsingCSV数据的SourceForge项目)
XML序列化框架应该是可扩展的,以便将大型(或大型)CSV文件转换为XML:我的build议是允许parsing和序列化的Sun JavastreamXMLparsing器框架(请参见此处 )。
据我所知,没有现成的库来为你做这件事,但是生成一个能够从CSV转换成XML的工具只需要你写一个粗糙的CSVparsing器,并把JDOM(或者你的XML Java库select)与一些胶水代码。
这可能太基本了,或者是有限的解决scheme,但是不能在文件的每一行都做一个String.split()
,记住第一行的结果数组来生成XML,并且只是吐出每一行的数组数据用正确的XML元素填充循环的每个迭代?
对于CSV部分,您可以使用我的小开源库
我有同样的问题,需要一个应用程序将CSV文件转换为我的项目之一的XML文件,但没有find任何自由和足够好的网上,所以我编写自己的Java Swing CSVtoXML应用程序。
它可以从我的网站在这里 。 希望它会帮助你。
如果没有,你可以像我一样轻松地编写你自己的代码。 源代码在jar文件中,如果不满足您的要求,请根据需要进行修改。
Jackson处理器家族拥有多种数据格式的后端,而不仅仅是JSON。 这包括XML( https://github.com/FasterXML/jackson-dataformat-xml )和CSV( https://github.com/FasterXML/jackson-dataformat-csv/ )后端。
转换将依赖于使用CSV后端读取input,使用XML后端进行写入。 如果您有(或可以定义)每行(CSV)条目的POJO,这是最容易做到的。 这不是一个严格的要求,因为来自CSV的内容也可能被读取为“无types”( String
数组序列),但是在XML输出上需要更多的工作。
对于XML方面,您需要一个包装器根对象来包含要序列化的数组或对象List
。