Java库或应用程序将CSV转换为XML文件?

nqui 发布于 2018-02-02 csv 最后更新 2018-02-02 15:40 3863 浏览

Java 中是否有现有的应用程序或库,允许我将CSV数据文件转换为XML文件? XML标签可能通过包含列标题的第一行提供。

已邀请:

tiste

赞同来自:

这可能太基本或者是有限的解决方案,但是你不能在文件的每一行上做一个String.split(),记住第一行的结果数组来产生XML,然后把每行的数组数据吐出XML元素填充循环的每个迭代?

ut_sit

赞同来自:

也许这可能有帮助:JSefa 您可以使用此工具读取CSV文件并将其序列化为XML。

jquia

赞同来自:

我不明白你为什么要这样做。这听起来像货物崇拜编码。 将CSV文件转换为XML不会添加任何值。你的程序已经在读取CSV文件了,所以争论说你需要XML不起作用。 另一方面,读取CSV文件,使用值来做 something ,然后序列化到XML确实是有意义的(就像使用XML可能是有意义的一样);但是你应该已经有了序列化XML的手段。

vomnis

赞同来自:

据我所知,没有现成的库来为你做这件事,但是生成一个能够从CSV转换成XML的工具只需要你写一个粗糙的CSV解析器,并把JDOM(或者你的XML Java库选择)与一些胶水代码。

fillum

赞同来自:

没有任何我知道的,可以做到这一点,没有你至少写一点代码...你将需要2个独立的库:

  • CSV解析器框架
  • XML序列化框架
  • 我建议的CSV解析器(除非你想有一个有趣的编写自己的CSV解析器)是OpenCSV(解析CSV数据的SourceForge项目) XML序列化框架应该是可扩展的,以便将大型(或大型)CSV文件转换为XML:我的建议是允许解析和序列化的Sun Java Streaming XML解析器框架(请参阅here)。

wnatus

赞同来自:

我知道你问了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])
            }
        }
    }
}
将以下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>
但是,代码做了非常简单的解析(不考虑引号或转义逗号),并没有考虑到可能缺少的数据。

caut

赞同来自:

此解决方案不需要任何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>

modit

赞同来自:

和其他人一样,我不知道有什么一步一步的办法,但是如果你准备使用非常简单的外部库,我会建议: OpenCsv解析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();
        }
    }
}
产生以下结果: (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>

wsed

赞同来自:

对于CSV部分,您可以使用my little open source library

inemo

赞同来自:

一般来说,我有一个用于处理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");
你将有一个解析对象的集合。 希望有所帮助!

hvelit

赞同来自:

Daniel Parker还有一个很好的图书馆ServingXML,它可以将几乎任何纯文本格式转换成XML格式。 可以找到您的案例here:它使用CSV文件中的字段标题作为XML元素名称。

wsed

赞同来自:

您可以使用Groovy异常简单地执行此操作,并且代码非常易读。 基本上,对于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>"""
}

iut

赞同来自:

您可以使用 XSLT 。谷歌它,你会发现一些例子,例如CSV to XML 如果您使用 XSLT ,则可以将XML转换为您想要的任何格式。

ieos

赞同来自:

最大的区别是JSefa引入的是它可以将您的java对象序列化到CSV/XML/etc文件,并可以反序列化回java对象。它是由注释驱动的,这使得您可以很好地控制输出。 JFileHelpers也看起来很有趣。

taut

赞同来自:

我有同样的问题,需要一个应用程序将CSV文件转换为我的项目之一的XML文件,但没有找到任何自由和足够好的网上,所以我编写自己的Java Swing CSVtoXML应用程序。 它可以从我的网站HERE获得。希望它会帮助你。 如果没有,你可以像我一样简单地编写你自己的代码。源代码在jar文件中,如果不满足您的要求,请根据需要进行修改。

guozao

赞同来自:

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