Java中是否存在允许我将CSV
数据文件转换为文件的现有应用程序或库XML
?
标签将XML
通过可能包含列标题的第一行提供。
也许这可能会有所帮助:JSefa
您可以使用此工具读取 CSV 文件并将其序列化为 XML。
和上面的其他人一样,我不知道任何一步的方法来做到这一点,但如果你准备好使用非常简单的外部库,我建议:
用于解析 CSV 的OpenCsv(小巧、简单、可靠且易于使用)
Xstream解析/序列化 XML(非常非常容易使用,并创建完全人类可读的 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 编写的快速(非常简单)的解决方案。
测试.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 写入标准输出:
<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 编写代码,例如:
@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;
}
然后只需使用以下方法解析您的文本文件:
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...
所以我们开始:
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 (从本页的另一个答案中窃取):
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>
我不明白你为什么要这样做。这听起来几乎像货物崇拜编码。
将 CSV 文件转换为 XML 不会增加任何价值。您的程序已经在读取 CSV 文件,因此认为您需要 XML 是行不通的。
另一方面,读取 CSV 文件,对值做一些事情,然后序列化为 XML 确实有意义(好吧,尽可能多地使用 XML 可以有意义......;))但你应该已经有了一种方法序列化为 XML。
最大的不同是JSefa带来的是它可以将你的 java 对象序列化为 CSV/XML/etc 文件,并且可以反序列化回 java 对象。它由注释驱动,使您可以对输出进行大量控制。
JFileHelpers 看起来也很有趣。
您可以使用 Groovy 非常轻松地做到这一点,并且代码非常易读。
contacts.xml
基本上,将为 中的每一行写入 text 变量contactData.csv
,并且 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>"""
}
您可以使用XSLT。谷歌它,你会发现一些例子,例如CSV 到 XML 如果你使用XSLT,你可以将 XML 转换成你想要的任何格式。
据我所知,没有现成的库可以为您执行此操作,但是生成能够从 CSV 转换为 XML 的工具只需要您编写一个粗略的 CSV 解析器并连接 JDOM(或您的 XML Java 库选择)带有一些胶水代码。
我所知道的没有任何东西可以在没有你至少编写一点代码的情况下做到这一点......你将需要 2 个单独的库:
我推荐的 CSV 解析器(除非你想有一点乐趣来编写自己的 CSV 解析器)是 OpenCSV(用于解析 CSV 数据的 SourceForge 项目)
XML 序列化框架应该是可以扩展的,以防您想将大型(或巨大)CSV 文件转换为 XML:我的建议是 Sun Java Streaming XML Parser Framework(参见此处),它允许拉解析和序列化。
Daniel Parker还有一个很好的ServingXML库,它能够将几乎任何纯文本格式转换为 XML 并返回。
可以在此处找到您的案例示例:它使用 CSV 文件中的字段标题作为 XML 元素名称。
这可能是一个太基本或有限的解决方案,但你不能String.split()
在文件的每一行上做一个,记住第一行的结果数组来生成 XML,然后用正确的 XML 吐出每一行的数组数据元素填充循环的每次迭代?
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
要序列化的数组或对象。
对于 CSV 部分,您可以使用我的小型开源库
我遇到了同样的问题,需要一个应用程序来为我的一个项目将 CSV 文件转换为 XML 文件,但在网上找不到任何免费且足够好的东西,所以我编写了自己的 Java Swing CSVtoXML 应用程序。
可从我的网站HERE获得。希望它会帮助你。
如果没有,您可以像我一样轻松编写自己的代码;源代码在 jar 文件中,如果不满足您的要求,请根据需要进行修改。