Java中是否存在现有的应用程序或库,可以将CSV数据文件转换为XML文件?
XML标签可能会通过包含列标题的第一行来提供。
也许这可能有所帮助:JSefa
您可以使用此工具读取CSV文件并将其序列化为XML。
与上述其他方法一样,我不知道任何一步式的方法,但是如果您准备使用非常简单的外部库,我建议:
用于解析CSV的OpenCsv(小巧,简单,可靠且易于使用)
用于解析/序列化XML的Xstream(非常易于使用,并创建完全可读的xml)
使用与上述相同的示例数据,代码如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| 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可以非常精细地调整结果...)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
| <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编写的快速(非常简单)的解决方案。
test.csv
1 2 3 4 5 6
| 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| #!/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写入标准输出:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| <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> |
但是,代码执行非常简单的解析(不考虑引号或转义的逗号),并且不考虑可能缺少的数据。
我有一个开放源代码框架,通常可以处理CSV和平面文件。也许值得一看:JFileHelpers。
使用该工具包,您可以使用bean编写代码,例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| @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;
} |
,然后使用以下命令解析文本文件:
1 2 3 4 5 6 7
| FileHelperEngine<Customer> engine =
new FileHelperEngine<Customer>(Customer.class);
List<Customer> customers =
new ArrayList<Customer>();
customers = engine.readResource(
"/samples/customers-fixed.txt"); |
您将拥有一组已解析的对象。
希望有帮助!
此解决方案不需要任何CSV或XML库,并且我知道它不会处理任何非法字符和编码问题,但是您也可能对此感兴趣,只要您的CSV输入不会违反上述规则。
注意:除非您知道自己的工作或没有机会使用其他库(在某些官僚项目中可能),否则不要使用此代码...对于较旧的运行时环境使用StringBuffer ... <铅>
所以我们开始:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| 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()); |
输入test.csv(从此页面上的另一个答案窃取):
1 2 3 4 5 6
| 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 |
结果输出:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| <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> |
JSefa带来的最大区别是,它可以将Java对象序列化为CSV / XML / etc文件,并可以反序列化回Java对象。它由注释驱动,可以对输出进行很多控制。
JFileHelpers也看起来很有趣。
您可以使用Groovy异常轻松地执行此操作,并且代码可读性强。
基本上,对于contactData.csv中的每一行,文本变量都将被写入contacts.xml,并且fields数组包含每一列。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| 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>
${fields[9]} </email>
password </employeenumber>
${fields[4]}
<phone> ${fields[3]} </phone>
</CLIENTS>"""
} |
我不明白您为什么要这么做。听起来几乎像是货物崇拜代码。
将CSV文件转换为XML不会增加任何值。您的程序已经在读取CSV文件,因此认为您需要XML无效。
另一方面,读取CSV文件,对值进行处理,然后序列化为XML确实有意义(嗯,与使用XML一样有意义……;)),但是您应该已经知道了一种序列化为XML的方法。
您可以使用XSLT。谷歌它,你会发现一些例子,例如CSV到XML
如果使用XSLT,则可以将XML转换为所需的任何格式。
Daniel Parker也提供了一个很好的ServingXML库,它能够将几乎所有纯文本格式转换为XML,然后转换为XML。
您的案例的示例可以在这里找到:它使用CSV文件中的字段标题作为XML元素名称。
据我所知,如果没有至少写一点点代码,没有什么能做到这一点……您将需要2个独立的库:
我推荐的CSV解析器(除非您想自己编写CSV解析器有一点乐趣)是OpenCSV(用于解析CSV数据的SourceForge项目)
XML序列化框架应该可以扩展,以防您要将大型(或巨大)CSV文件转换为XML:我的建议是Sun Java Streaming XML Parser框架(请参见此处),该框架允许进行拉式分析和序列化。
据我所知,尚没有现成的库可以为您完成此操作,但是生产能够将CSV转换为XML的工具只需要编写一个简单的CSV解析器并连接JDOM(或XML)即可。选择的Java库)和一些粘合代码。
Jackson处理器家族的后端具有多种数据格式,而不仅仅是JSON。这包括XML(https://github.com/FasterXML/jackson-dataformat-xml)和CSV(https://github.com/FasterXML/jackson-dataformat-csv/)后端。
转换将取决于使用CSV后端读取输入,使用XML后端写入。如果您具有(或可以定义)每行(CSV)条目的POJO,这是最容易做到的。这不是严格的要求,因为来自CSV的内容也可以被"无类型"读取(String数组的序列),但是需要更多的XML输出工作。
对于XML端,您需要一个包装器根对象来包含要序列化的对象数组或List。
这可能太基本或仅受解决方案限制,但是您不能在文件的每一行上执行String.split(),记住第一行的结果数组以生成XML,而只是吐出每一行的数组用适当的XML元素填充数据以填充循环的每次迭代?
我遇到了同样的问题,需要一个应用程序将一个项目的CSV文件转换为XML文件,但是在网上找不到任何免费且足够好的东西,所以我编写了自己的Java Swing CSVtoXML应用程序。
可以在我的网站上找到。希望对您有帮助。
如果没有,您可以像我一样轻松地编写自己的代码;源代码位于jar文件中,因此如果它不能满足您的要求,请根据需要进行修改。
对于CSV部分,您可以使用我的开放源代码库