2008-08-01 171 views
92

是否有現有的應用程序或庫Java這將允許我將CSV數據文件轉換爲XML文件?Java庫或應用程序將CSV轉換爲XML文件?

XML標記將通過可能包含列標題的第一行提供。

+33

看來,這是第一個帶有Java標籤的問題。 – 2013-09-12 21:24:53

+6

@保羅不僅如此,它也是123! – bjb568 2014-02-22 06:35:03

+0

@ bjb568你是什麼意思? – CodingNinja 2017-07-09 18:28:19

回答

59

也許這可能幫助:JSefa

可以讀取CSV文件,用這個工具,並將其序列化到XML。

4

這可能太基本或者只限於解決方案,但是不能在文件的每一行上執行String.split(),記住第一行的結果數組以生成XML,並且只是吐出每行的數組數據用合適的XML元素填充循環的每個迭代?

+1

如果您的CSV文件在數據中包含帶引號的逗號(相當常見),則不適用。 – 2010-07-07 16:19:43

13

我不明白你爲什麼想要這樣做。這聽起來像貨物崇拜編碼。

將CSV文件轉換爲XML不會添加任何值。您的程序已在讀取CSV文件,因此爭辯說您需要XML不起作用。另一方面,閱讀CSV文件,做東西與值,然後序列化到XML確實是有道理的(好,儘可能多的使用XML可以... ...)),但你會據說已經有序列化XML的手段。

7

據我所知,目前還沒有現成的庫來爲你做這件事,但是生成一個能夠從CSV轉換爲XML的工具應該只需要你編寫一個粗略的CSV解析器並掛接JDOM(或者你的XML Java庫的選擇)與一些膠水代碼。

7

沒有什麼,我知道的,可以做到這一點,沒有你至少寫的代碼一點點......你需要2個獨立的庫:

  • 一個CSV分析器框架
  • 的XML序列化框架

的CSV解析器我建議(除非你想有一個有趣的一點編寫自己的CSV分析器)是OpenCSV(SourceForge專案解析CSV數據)

如果您想將大型(或大型)CSV文件轉換爲XML,那麼XML序列化框架應該是可擴展的:我的建議是Sun Java Streaming XML Parser Framework(請參閱here),它允許進行解析和序列化。

24

我知道你問了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。常規

#!/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> 

但是,代碼確實非常簡單解析(不考慮引用或轉義逗號),它並沒有考慮可能存在數據。

15

該解決方案不需要任何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> 
44

如上別人,我不知道任何一個步驟的方式做到這一點,但如果你已經準備好使用非常簡單的外部庫,我建議:

OpenCsv解析CSV(小型,簡單,可靠和易於使用)

西河解析/ 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(); 
     } 
    } 
} 

產生以下結果: (西河允許結果的非常微調...)

<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> 
17

我有一個與CSV和一般的平面文件工作的開源框架。也許這是值得期待:JFileHelpers

隨着該工具包可以使用豆類,如編寫代碼:

@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"); 

而且你必須解析的對象的集合。

希望幫助!

8

Daniel Parker也有不錯的圖書館ServingXML,它能夠將幾乎任何純文本格式轉換爲XML並返回。

可以找到您的案例的示例here:它使用CSV文件中字段的標題作爲XML元素名稱。

15

您可以非常容易地使用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>""" 
} 
11

你可以使用XSLT 。谷歌它,你會發現一些例子,例如CSV to XML 如果您使用XSLT然後您可以將XML轉換爲您想要的任何格式。

14

最大的區別是JSefa引入的是它可以將您的java對象序列化爲CSV/XML/etc文件,並可以反序列化回java對象。它由註釋驅動,可以讓您對輸出進行很多控制。

JFileHelpers看起來也很有趣。

3

我有同樣的問題,需要一個應用程序將CSV文件轉換爲我的項目之一的XML文件,但沒有發現任何自由和足夠好的網絡,所以我編碼我自己的Java Swing CSVtoXML應用。

它可從我的網站HERE。希望它能幫助你。

如果不是,您可以像我一樣輕鬆編寫自己的代碼;源代碼位於jar文件中,因此如果不滿足您的要求,請根據需要對其進行修改。

3

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