CSVをXMLファイルに変換するJava libまたはアプリ?[閉まっている]


114

データファイルをファイルに変換できるJavaの既存のアプリケーションまたはライブラリはありますか? CSVXML

XMLタグは、列見出しを含む可能性の最初の行を介して提供されます。


47
これは、SOでのJavaタグの最初の質問のようです。
Paul Vargas

8
@Paulそれだけでなく、123でもあります。
bjb568 14


1
@ bjb568ああ。haha

4
SOでのJavaの最初の投稿がオフトピックとして閉じられたことも不思議ではありません:D
サー。ハリネズミ

回答:


66

多分これは役立つかもしれません:JSefa

このツールでCSVファイルを読み取り、XMLにシリアル化できます。


47

上記の他の方法と同様に、私はそれを行うためのワンステップの方法を知りませんが、非常に単純な外部ライブラリを使用する準備ができている場合は、以下をお勧めします。

OpenCsvCSVを解析するための(小さく、シンプルで、信頼性が高く、使いやすい)

XstreamXMLを解析/シリアル化する(非常に使いやすく、完全に人間が読める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>

27

あなたが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>

ただし、コードは非常に単純な解析(引用符付きまたはエスケープされたコンマを考慮しない)を実行し、存在しない可能性のあるデータを考慮しません。


したがって、CSVライブラリを呼び出して解析を行い、マークアップビルダーを使用できます。多分あなたはこれを示すためにあなたの答えを編集することができます。
ピーターケリー

18

私は一般的に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以降の新しいバージョンがないようです...
ステファン

はい、それ以来、開発を続ける時間はありませんでしたが、非常に安定しています。
kolrie

17

このソリューションは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>

15

JSefaがもたらす大きな違いは、JavaオブジェクトをCSV / XML / etcファイルにシリアル化し、逆シリアル化してJavaオブジェクトに戻すことができることです。そして、それはあなたがあなたに出力の多くの制御を与えるアノテーションによって駆動されます。

JFileHelpersも興味深いようです。


14

なぜこれをしたいのかわかりません。貨物カルトコーディングのように聞こえます。

CSVファイルをXMLに変換しても、値は追加されません。プログラムは既にCSVファイルを読み込んでいるため、XMLが必要であると主張しても機能しません。

一方、CSVファイルを読み取り、値を使用して何かを実行し、XMLにシリアル化することは理にかなっています(まあ、XMLを使用するのは理にかなっています...;))おそらくすでに手段を持っているでしょう。 XMLへのシリアル化。


14

これはGroovyを使用して非常に簡単に行うことができ、コードは非常に読みやすくなっています。

基本的に、テキスト変数はのcontacts.xml各行に書き込まれ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>"""
}

7
CSVは単純ですが、コンマでの分割で十分であるほど単純ではありません。
Alan Krueger

12

XSLTを使用できます。それをグーグルすると、CSVからXMLなどのいくつかの例が見つかります。XSLTを 使用すると、XMLを任意の形式に変換できます。


8

優れたライブラリServingXMLもありますDaniel Parkerによる、ほとんどすべてのプレーンテキスト形式をXMLに変換したり、XMLに戻したりできます。

あなたのケースの例はここにあります:XML要素名としてCSVファイルのフィールドの見出しを使用します。


7

あなたが少なくとも少しのコードを書かずにこれを行うことができると私が知っていることは何もありません...あなたは2つの別々のライブラリが必要になります:

  • CSVパーサーフレームワーク
  • XMLシリアル化フレームワーク

私がお勧めするCSVパーサー(独自のCSVパーサーを書くのが少し面白くない限り)は、OpenCSV(CSVデータを解析するためのSourceForgeプロジェクト)です。

私の推薦は、SunのJavaストリーミングXMLパーサーのフレームワークである(参照:XMLシリアル化フレームワークを使用すると、XMLに大きな(または巨大な)CSVファイルを変換したい場合に拡張できるものである必要があり、ここで)プル解析およびシリアライズすることができます。


7

私の知る限り、これを行うための既製のライブラリはありませんが、CSVからXMLに変換できるツールを作成するには、大まかなCSVパーサーを記述してJDOM(またはXML Javaライブラリ選択)いくつかのグルーコード付き。


4

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シリアル化するオブジェクトまたはオブジェクトの配列を含むラッパールートオブジェクトが必要になります。


3

私も同じ問題を抱えており、プロジェクトの1つでCSVファイルをXMLファイルに変換するアプリケーションが必要でしたが、ネット上で無料で十分なものが見つからなかったため、独自のJava Swing CSVtoXMLアプリケーションをコーディングしました。

こちらのウェブサイトから入手できます。それがあなたを助けることを願っています。

そうでない場合は、私と同じように簡単に独自にコーディングできます。ソースコードはjarファイル内にあるため、要件を満たさない場合は必要に応じて変更してください。



3

これはあまりにも基本的または制限されたソリューションである可能性がありますString.split()が、ファイルの各行で実行できません。最初の行の結果配列を思い出してXMLを生成し、適切なXMLで各行の配列データを吐き出します。ループの各反復を埋める要素?


2
CSVファイルのデータに引用符で囲まれたコンマが含まれている場合は、これはかなり一般的です。
Alan Krueger
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.