Java lib oder App CSV to XML-Datei zu konvertieren?

stimmen
95

Gibt es eine bestehende Anwendung oder Bibliothek in Java , die mir erlauben , eine zu konvertieren CSVDatendatei - XMLDatei?

Die XMLTags würden möglicherweise durch die erste Zeile mit Spaltenüberschriften zur Verfügung gestellt werden.

Veröffentlicht am 01/08/2008 um 17:08
quelle vom benutzer
In anderen Sprachen...                            


16 antworten

stimmen
60

Vielleicht helfen könnte dies: JSefa

Sie können CSV-Datei mit diesem Tool lesen und Serialisierung in XML.

Beantwortet am 01/08/2008 um 19:51
quelle vom benutzer

stimmen
45

Wie die andere oben, weiß ich nicht in einem Schritt Weg, dies zu tun, aber wenn Sie bereit sind, sehr einfach externe Bibliotheken zu verwenden, würde ich vorschlagen:

OpenCsv für Parsing CSV (kleine, einfache, zuverlässige und einfach zu bedienen)

Xstream zu analysieren / serialisiert XML (sehr sehr einfach zu bedienen und vollständig für Menschen lesbare XML - Erstellung)

Unter Verwendung der gleichen Beispieldaten wie oben, Code würde wie folgt aussehen:

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

Herstellung folgendes Ergebnis: (Xstream ermöglicht eine sehr feine Abstimmung des Ergebnisses ...)

<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>
Beantwortet am 10/09/2008 um 08:06
quelle vom benutzer

stimmen
24

Ich weiß, dass Sie für Java gefragt, aber dies scheint mir eine Aufgabe gut geeignet, um eine Skriptsprache. Hier ist eine kurze (sehr einfach) Lösung in Groovy geschrieben.

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])
            }
        }
    }
}

Schreibt die folgenden XML zu 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>

Allerdings ist der Code sehr einfaches Parsing (ohne Berücksichtigung zitiert oder entkam Komma) und es nicht für möglich fehlen Daten zu berücksichtigen.

Beantwortet am 09/08/2008 um 12:06
quelle vom benutzer

stimmen
17

Ich habe eine Open - Source - Framework für mit CSV und Textdateien in der Regel arbeiten. Vielleicht ist es ein Blick wert: JFileHelpers .

Mit diesem Toolkit können Sie Code schreiben, Bohnen verwenden, wie:

@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;  
}

und dann analysieren Sie einfach Ihre Text-Dateien mit:

FileHelperEngine<Customer> engine = 
    new FileHelperEngine<Customer>(Customer.class); 
List<Customer> customers = 
    new ArrayList<Customer>();

customers = engine.readResource(
    "/samples/customers-fixed.txt");

Und Sie werden eine Sammlung von analysierten Objekte.

Ich hoffe, das hilft!

Beantwortet am 28/09/2008 um 00:43
quelle vom benutzer

stimmen
15

Diese Lösung, die keine CSV oder XML-Bibliotheken benötigt, und ich weiß, ist es keine ungültigen Zeichen und Codierung Probleme zu behandeln, aber Sie könnten auch daran interessiert sein, vorausgesetzt, Ihr CSV-Eingang die oben genannten Regeln nicht bricht.

Achtung: Sie sollten diesen Code nicht verwenden , wenn Sie wissen , was Sie tun oder haben nicht die Möglichkeit , eine weitere Bibliothek zu verwenden (möglich in einigen bürokratischen Projekte) ... ein String für ältere Laufzeitumgebungen verwenden ...

Auf geht's:

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

Der Eingang test.csv (aus einer anderen Antwort auf dieser Seite gestohlen):

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

Die resultierende Ausgabe:

<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>
Beantwortet am 22/08/2008 um 00:17
quelle vom benutzer

stimmen
14

Der große Unterschied ist , dass JSefa in bringt , ist , dass es Ihre Java - Objekte in CSV / XML / etc Dateien serialisiert werden kann und auf Java - Objekte deserialisiert zurück. Und es ist durch Anmerkungen angetrieben , die Ihnen viel Kontrolle über den Ausgang gibt.

JFileHelpers sieht auch interessant.

Beantwortet am 11/08/2010 um 06:49
quelle vom benutzer

stimmen
14

Sie können dies tun, außergewöhnlich leicht Groovy verwenden, und der Code ist sehr gut lesbar.

Grundsätzlich wird die Textvariable geschrieben wird contacts.xmlin der für jede Zeile contactData.csv, und die Felder Array enthält jede Spalte.

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>"""
}
Beantwortet am 02/10/2008 um 07:08
quelle vom benutzer

stimmen
13

Ich verstehe nicht, warum Sie dies tun wollen. Es klingt fast wie Cargo-Kult-Codierung.

wird eine CSV-Datei, um XML-Konvertierung von keinem Wert hinzufügen. Ihr Programm liest schon die CSV-Datei, so argumentieren, dass Sie benötigen XML funktioniert nicht.

Auf der anderen Seite, die CSV - Datei zu lesen, tun etwas mit den Werten und dann auf XML - Serialisierung macht Sinn (na ja, so viel wie XML kann Sinn machen ...;)) , aber sie hätte angeblich bereits ein Mittel Serialisierung in XML.

Beantwortet am 01/08/2008 um 20:21
quelle vom benutzer

stimmen
11

Sie könnten verwenden XSLT . Google es und Sie werden einige Beispiele zum Beispiel finden CSV to XML Wenn Sie XSLT Sie können dann wandeln das XML - Format, was auch immer Sie wollen.

Beantwortet am 16/10/2008 um 15:33
quelle vom benutzer

stimmen
8

Es gibt auch gute Bibliothek ServingXML von Daniel Parker, die fast jedes Textformat in XML und zurück umwandeln können.

Das Beispiel für den Fall gefunden werden hier : Es verwendet Überschrift Feld in CSV - Datei als XML - Elementname.

Beantwortet am 30/09/2008 um 22:22
quelle vom benutzer

stimmen
7

Es gibt nichts, was ich kenne, dass dies tun können, ohne dass Sie zumindest ein wenig Code schreiben ... Sie müssen zwei separate Bibliothek:

  • Ein CSV-Parser-Framework
  • Ein XML-Serialisierung Rahmen

Die CSV-Parser ich empfehlen würde (es sei denn, Sie ein wenig Spaß haben wollen Sie Ihre eigenen CSV Parser zu schreiben) ist OpenCSV (A Source Projekt zum Parsen von CSV-Daten)

Der XML - Serialisierung Rahmen sollte etwas sein , den Fall skalieren können Sie große (oder große) CSV - Datei in XML transformiert werden sollen: Meine Empfehlung ist , die Sun Java Streaming XML Parser Framework (siehe hier ) , die Pull-Analyse und Serialisierung ermöglicht.

Beantwortet am 04/08/2008 um 02:07
quelle vom benutzer

stimmen
7

Soweit ich weiß, gibt es keine fertige Bibliothek dies für Sie tun, sondern ein Werkzeug, das die Übersetzung von CSV to XML produziert nur, benötigen Sie einen rohe CSV-Parser zu schreiben und bis JDOM Haken (oder XML-Java-Bibliothek Wahl) mit einem Tropfen Klebstoff-Code.

Beantwortet am 02/08/2008 um 20:06
quelle vom benutzer

stimmen
4

Jackson - Prozessorfamilie hat Backends für mehrere Datenformate, nicht nur JSON. Dazu gehören sowohl XML ( https://github.com/FasterXML/jackson-dataformat-xml ) und CSV ( https://github.com/FasterXML/jackson-dataformat-csv/ ) Backends.

Umwandlung würde verlassen sich auf Eingangs Lesen mit CSV - Backend, schreiben XML - Backend verwenden. Dies ist am einfachsten zu tun , wenn Sie (oder definieren kann) eine POJO für pro-Zeile (CSV) Einträge. Dies ist keine strenge Anforderung, wie Inhalte von CSV können „untypisierten“ als auch (eine Folge von gelesen werden StringArrays), aber etwas mehr Arbeit auf XML - Ausgabe erfordert.

Für XML - Seite, würden Sie ein Wrapper - Root - Objekt benötigen Array enthalten oder Listvon Objekten zu serialisiert.

Beantwortet am 29/04/2015 um 20:01
quelle vom benutzer

stimmen
3

Ich hatte das gleiche Problem und eine Anwendung benötigt, um eine CSV-Datei in eine XML-Datei für ein meine Projekte zu konvertieren, aber nichts frei und gut genug, um im Netz finden, so dass ich meine eigene codierten Java Swing CSVtoXML Anwendung.

Es ist von meiner Website verfügbar HIER . Hoffe , es wird Ihnen helfen.

Wenn nicht, können Sie einfach Ihre eigenen Code wie ich es tat; Der Quellcode ist innerhalb der JAR-Datei es so ändern, wie Sie benötigen, wenn es Ihre Anforderung nicht erfüllen.

Beantwortet am 16/04/2014 um 01:12
quelle vom benutzer

stimmen
3

Für den CSV - Teil, können Sie verwenden , meine kleine Open - Source - Bibliothek

Beantwortet am 16/09/2008 um 17:07
quelle vom benutzer

stimmen
3

Dies kann zu einfach sein , oder einer Lösung begrenzt, aber könnten Sie nicht tun , String.split()auf jeder Zeile der Datei, um das Ergebnis Feld der ersten Linie der Erinnerung an die XML zu generieren, und spuckt nur jede Array Linie Daten aus mit der richtigen XML Elemente Klotzen bei jeder Iteration einer Schleife?

Beantwortet am 01/08/2008 um 17:31
quelle vom benutzer

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more