将CSV转换为XML文件的Java库或应用程序?
是否有Java中的现有应用程序或库允许我将将CSV转换为XML文件的Java库或应用程序?,java,xml,csv,data-conversion,Java,Xml,Csv,Data Conversion,是否有Java中的现有应用程序或库允许我将CSV数据文件转换为XML文件 XML标记可能会通过包含列标题的第一行提供。这可能太基本或解决方案有限,但您不能在文件的每一行上都做一个标记,记住第一行的结果数组来生成XML,只要用适当的XML元素填充循环的每个迭代,就可以将每行的数组数据吐出来?也许这会有帮助: 您可以使用此工具读取CSV文件并将其序列化为XML。我不明白您为什么要这样做。这听起来几乎像是货物崇拜编码 将CSV文件转换为XML不会增加任何价值。您的程序已经在读取CSV文件,因此认为您需
CSV
数据文件转换为XML
文件
XML
标记可能会通过包含列标题的第一行提供。这可能太基本或解决方案有限,但您不能在文件的每一行上都做一个标记,记住第一行的结果数组来生成XML,只要用适当的XML元素填充循环的每个迭代,就可以将每行的数组数据吐出来?也许这会有帮助:
您可以使用此工具读取CSV文件并将其序列化为XML。我不明白您为什么要这样做。这听起来几乎像是货物崇拜编码 将CSV文件转换为XML不会增加任何价值。您的程序已经在读取CSV文件,因此认为您需要XML是行不通的
另一方面,读取CSV文件,对值做一些处理,然后序列化为XML是有意义的(就像使用XML一样有意义……;),但你应该已经有了序列化为XML的方法。据我所知,没有现成的库可以为你做这件事,但是,生成一个能够从CSV转换为XML的工具只需要编写一个粗糙的CSV解析器,并用一些粘合代码连接JDOM(或您选择的XML Java库)。我所知,没有任何工具可以做到这一点,至少需要您编写一点代码。。。您将需要两个独立的库:
- CSV解析器框架
- XML序列化框架
XML序列化框架应该可以扩展,以防您想要将大型(或巨大)CSV文件转换为XML:我推荐Sun Java Streaming XML Parser Framework(请参阅),它允许拉式解析和序列化。我知道您要求Java,但我觉得这是一项非常适合脚本语言的任务。下面是一个用Groovy编写的快速(非常简单)解决方案 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])
}
}
}
}
#/usr/bin/env groovy
def csvdata=[]
新文件(“test.csv”).eachLine{line->
csvdata
//写入具有“id”属性的“entry”元素
条目(id:索引+1){
headers.eachWithIndex{heading,i->
//写下每个标题和相关内容
“${heading}”(数据行[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>
你好,世界
1
3.3
4.
再见世界
1e9
-3.3
45
你好
-1
23.33
456
你好,世界3
1.40
34.83
4999
你好2世界
9981.05
43.33
444
但是,代码进行非常简单的解析(不考虑引号或转义逗号),并且不考虑可能缺少的数据。此解决方案不需要任何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());
结果输出:
<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>
你好,世界
1
3.3
4.
再见世界
1e9
-3.3
45
你好
-1
23.33
456
你好,世界3
1.40
34.83
4999
你好2世界
9981.05
43.33
444
与上述其他方法一样,我不知道如何一步到位,但如果您准备好使用非常简单的外部库,我建议:
用于解析CSV(小型、简单、可靠且易于使用)
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();
}
}
}
包装fr.megiste.test;
导入java.io.FileReader;
导入java.io.FileWriter;
导入java.util.ArrayList;
导入java.util.List;
导入au.com.bytecode.opencsv.CSVReader;
导入com.thoughtworks.xstream.xstream;
公共类CsvToXml{
公共静态void main(字符串[]args){
字符串startFile=“./startData.csv”;
字符串outFile=“./outData.xml”;
试一试{
CSVReader reader=newcsvreader(newfilereader(startFile));
字符串[]行=null;
String[]header=reader.readNext();
List out=new ArrayList();
而((line=reader.readNext())!=null){
列表项=新建ArrayList();
对于(int i=0;i
产生以下结果:
(Xstream允许对结果进行非常精细的调整…)
一串
你好,世界
浮动1
1
浮动2
3.3
整数
4.
一串
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();
}
}
}
<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>
@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");
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>"""
}