【问题标题】:Java lib or app to convert CSV to XML file? [closed]将 CSV 转换为 XML 文件的 Java lib 或应用程序? [关闭]
【发布时间】:2010-09-05 05:37:15
【问题描述】:

Java 中是否存在允许我将 CSV 数据文件转换为 XML 文件的应用程序或库?

XML 标签可能通过包含列标题的第一行提供。

【问题讨论】:

  • 看来这是SO中带有Java标签的第一个问题。
  • @Paul 不仅如此,还是 123!
  • @bjb568 哦。哈哈
  • 难怪第一个关于 SO 中 java 的帖子被关闭为题外话:D

标签: java xml csv data-conversion


【解决方案1】:

也许这可能会有所帮助:JSefa

您可以使用此工具读取 CSV 文件并将其序列化为 XML。

【讨论】:

    【解决方案2】:

    和上面的其他人一样,我不知道任何一步的方法来做到这一点,但如果你准备好使用非常简单的外部库,我建议:

    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>
    

    【讨论】:

      【解决方案3】:

      我知道您要求使用 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 写入标准输出:

      <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 库进行解析,然后使用标记生成器。也许您可以编辑您的答案以显示这一点。
      【解决方案4】:

      我有一个用于处理 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");
      

      您将拥有一个已解析对象的集合。

      希望有帮助!

      【讨论】:

      • +1 用于注释的使用。不幸的是,截至今天,该项目似乎自 2009-08-11 以来没有任何新版本......
      • 是的,从那以后我没有时间继续开发,但它非常稳定。
      【解决方案5】:

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

      【讨论】:

        【解决方案6】:

        我不明白你为什么要这样做。这听起来几乎像货物崇拜编码。

        将 CSV 文件转换为 XML 不会增加任何价值。您的程序已经在读取 CSV 文件,因此认为您需要 XML 是行不通的。

        另一方面,读取 CSV 文件,对值进行 一些操作,然后将其序列化为 XML 确实有意义(好吧,尽可能多地使用 XML 是有意义的......;) ) 但您应该已经有一种序列化为 XML 的方法。

        【讨论】:

          【解决方案7】:

          最大的区别在于JSefa 带来的是它可以将你的java 对象序列化为CSV/XML/etc 文件,并且可以反序列化回java 对象。它由注释驱动,使您可以对输出进行大量控制。

          JFileHelpers 看起来也很有趣。

          【讨论】:

            【解决方案8】:

            您可以使用 Groovy 非常轻松地做到这一点,并且代码非常易读。

            基本上,对于contactData.csv 中的每一行,文本变量都会写入contacts.xml,并且字段数组包含每一列。

            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>"""
            }
            

            【讨论】:

            • CSV 很简单,但通常不够简单,以逗号分隔就足够了。
            【解决方案9】:

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

            【讨论】:

              【解决方案10】:

              Daniel Parker 还有一个很好的库ServingXML,它几乎可以将任何纯文本格式转换为 XML 格式并返回。

              您的案例示例可以在here找到:它使用CSV文件中的字段标题作为XML元素名称。

              【讨论】:

                【解决方案11】:

                如果你不写一点代码,我所知道的没有什么可以做到这一点...你需要 2 个独立的库:

                • CSV 解析器框架
                • XML 序列化框架

                我推荐的 CSV 解析器(除非您想获得一点乐趣来编写自己的 CSV 解析器)是 OpenCSV(用于解析 CSV 数据的 SourceForge 项目)

                XML 序列化框架应该是可以扩展的,以防您想将大型(或巨大)CSV 文件转换为 XML:我的建议是 Sun Java Streaming XML Parser Framework(参见 here),它允许拉解析AND 序列化。

                【讨论】:

                  【解决方案12】:

                  据我所知,没有现成的库可以为您执行此操作,但是生成能够从 CSV 转换为 XML 的工具只需要您编写一个粗略的 CSV 解析器并连接 JDOM(或您的 XML选择的 Java 库)带有一些胶水代码。

                  【讨论】:

                    【解决方案13】:

                    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 对象。

                    【讨论】:

                      【解决方案14】:

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

                      【讨论】:

                      • 如果您的 CSV 文件曾经在数据中包含带引号的逗号,则不会,这很常见。
                      【解决方案15】:

                      我遇到了同样的问题,需要一个应用程序来为我的一个项目将 CSV 文件转换为 XML 文件,但是在网上找不到任何免费且足够好的东西,所以我编写了自己的 Java Swing CSVtoXML 应用程序.

                      可从我的网站HERE 获得。希望它会帮助你。

                      如果没有,您可以像我一样轻松编写自己的代码;源代码在 jar 文件中,如果不满足您的要求,请根据需要进行修改。

                      【讨论】:

                        【解决方案16】:

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

                        【讨论】:

                          猜你喜欢
                          • 2014-07-24
                          • 1970-01-01
                          • 1970-01-01
                          • 2014-02-20
                          • 2016-07-21
                          • 1970-01-01
                          • 1970-01-01
                          • 2018-12-30
                          • 1970-01-01
                          相关资源
                          最近更新 更多