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

StackOverflow https://stackoverflow.com/questions/123

  •  08-06-2019
  •  | 
  •  

質問

既存のアプリケーションまたはライブラリはありますか ジャワ これにより、 CSV データファイルを XML ファイル?

XML タグは、列見出しを含む最初の行を通じて提供される可能性があります。

役に立ちましたか?

解決

おそらくこれが役立つかもしれません: ジェセファ

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

他のヒント

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

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();
        }
    }
}

次の結果が生成されます。(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>

Java をお求めになったことは承知していますが、これはスクリプト言語に適したタスクであるように思えます。ここでは、Groovy で書かれた簡単な (非常にシンプルな) ソリューションを示します。

テスト.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 ファイルとフラット ファイル全般を操作するためのオープンソース フレームワークを持っています。おそらくそれは一見の価値があります: 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");

そして、解析されたオブジェクトのコレクションが得られます。

お役に立てば幸いです!

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

大きな違いは、 ジェセファ 利点は、Java オブジェクトを CSV/XML/etc ファイルにシリアル化し、逆シリアル化して Java オブジェクトに戻すことができることです。また、アノテーションによって駆動されるため、出力を大幅に制御できます。

JFileHelpers も面白そうです。

なぜこんなことをしたいのか理解できません。カーゴカルトのコーディングのように聞こえます。

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

一方、CSVファイルを読み込むと、 何か 値を使用して XML にシリアル化するのは意味があります (XML を使用するのと同じくらい意味があります...);)) しかし、XML にシリアル化する手段はすでにあるはずです。

Groovy を使用すると、これを非常に簡単に実行でき、コードは非常に読みやすくなります。

基本的に、テキスト変数は次の場所に書き込まれます。 contacts.xml の各行に対して contactData.csv, 、フィールド配列には各列が含まれます。

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

使用できます XSLT. 。Googleで検索すると、いくつかの例が見つかります。 CSVからXMLへ使用する場合 XSLT その後、XML を任意の形式に変換できます。

充実した図書館もあります XML の提供 Daniel Parker によるもので、ほぼすべてのプレーン テキスト形式を XML に変換したり、逆に変換したりすることができます。

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

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

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

私がお勧めする CSV パーサーは (独自の CSV パーサーを作成して少し楽しみたい場合を除く)、OpenCSV (CSV データを解析するための SourceForge プロジェクト) です。

XML シリアル化フレームワークは、大きな (巨大な) CSV ファイルを XML に変換する場合に備えて拡張できるものである必要があります。私のお勧めは、Sun Java Streaming XML Parser Framework (「 ここ) これにより、プル解析とシリアル化が可能になります。

私の知る限り、これを行うための既製のライブラリはありませんが、CSV から XML に変換できるツールを作成するには、粗雑な CSV パーサーを作成し、JDOM (または XML Java ライブラリ) を接続するだけで済みます。選択) いくつかの接着コードを使用します。

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 シリアル化するオブジェクトの数。

これはあまりにも基本的または限定的な解決策かもしれませんが、次のことはできませんか? String.split() ファイルの各行で、最初の行の結果配列を記憶して XML を生成し、ループの各反復を埋める適切な XML 要素を使用して各行の配列データを吐き出すだけですか?

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

私のウェブサイトから入手できます ここ. 。お役に立てば幸いです。

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

CSV 部分には、次のものを使用できます。 私の小さなオープンソース ライブラリ

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top