java - mkyong - spring tutorial




Java-Bibliothek oder App zum Konvertieren von CSV in XML-Datei? (11)

Gibt es eine vorhandene Anwendung oder Bibliothek in Java, mit der ich eine CSV -Datendatei in eine XML Datei konvertieren kann?

Die XML Tags würden möglicherweise durch die erste Zeile mit Spaltenüberschriften bereitgestellt.


Der große Unterschied, den JSefa bringt, ist, dass es Ihre Java-Objekte in CSV / XML / etc-Dateien serialisieren und zurück in Java-Objekte deserialisieren kann. Und es wird von Anmerkungen angetrieben, die Ihnen viel Kontrolle über die Ausgabe geben.

JFileHelpers sieht auch interessant aus.


Die Jackson-Prozessorfamilie bietet Backends für mehrere Datenformate, nicht nur für JSON. Dies umfasst sowohl XML- ( https://github.com/FasterXML/jackson-dataformat-xml ) als auch CSV-Backends ( https://github.com/FasterXML/jackson-dataformat-csv/ ).

Die Konvertierung würde sich auf das Lesen von Eingaben mit dem CSV-Backend und das Schreiben mit dem XML-Backend stützen. Dies ist am einfachsten, wenn Sie ein POJO für Einträge pro Zeile (CSV) haben (oder definieren können). Dies ist keine strenge Anforderung, da der Inhalt von CSV auch "untypisiert" gelesen werden kann (eine Folge von String Arrays), erfordert jedoch etwas mehr Arbeit bei der XML-Ausgabe.

Für die XML-Seite benötigen Sie ein Wrapper-Stammobjekt, das ein Array oder eine List von Objekten enthält, die serialisiert werden sollen.


Diese Lösung benötigt keine CSV- oder XML-Bibliotheken und behandelt, wie ich weiß, keine illegalen Zeichen und Kodierungsprobleme. Sie könnten jedoch auch daran interessiert sein, vorausgesetzt, Ihre CSV-Eingabe verstößt nicht gegen die oben genannten Regeln.

Achtung: Sie sollten diesen Code nur verwenden, wenn Sie wissen, was Sie tun oder nicht in der Lage sind, eine weitere Bibliothek zu verwenden (in einigen bürokratischen Projekten möglich) ... Verwenden Sie einen StringBuffer für ältere Laufzeitumgebungen ...

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

Die Eingabe test.csv (gestohlen von einer anderen Antwort auf dieser Seite):

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>

Es gibt auch eine gute Bibliothek ServingXML von Daniel Parker, die nahezu jedes ServingXML Text-Format in XML und zurück konvertieren kann.

Das Beispiel für Ihren Fall finden Sie here : Als XML-Elementname wird die Überschrift des Felds in der CSV-Datei verwendet.


Ich habe ein OpenSource-Framework für die Arbeit mit CSV- und Flat-Files im Allgemeinen. Vielleicht lohnt es sich zu schauen: JFileHelpers .

Mit diesem Toolkit können Sie Code mit Beans schreiben, wie zum Beispiel:

@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 Textdateien 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 geparster Objekte haben.

Hoffentlich hilft das!


Ich hatte das gleiche Problem und brauchte eine Anwendung, um eine CSV-Datei in eine XML-Datei für eines meiner Projekte zu konvertieren, fand aber im Internet nichts, was frei und gut genug war. Deshalb habe ich meine eigene Java Swing CSVtoXML-Anwendung codiert.

Es ist auf meiner Website HERE verfügbar. Hoffe es wird dir helfen.

Wenn nicht, können Sie ganz einfach Ihren eigenen Code erstellen, wie ich es getan habe. Der Quellcode befindet sich in der JAR-Datei. Ändern Sie ihn nach Bedarf, wenn er Ihre Anforderungen nicht erfüllt.


Ich weiß nichts, was dies tun kann, ohne dass Sie zumindest ein bisschen Code schreiben ... Sie benötigen zwei separate Bibliotheken:

  • Ein CSV-Parser-Framework
  • Ein XML-Serialisierungsframework

Der CSV-Parser, den ich empfehlen würde (es sei denn, Sie möchten ein bisschen Spaß daran haben, Ihren eigenen CSV-Parser zu schreiben), ist OpenCSV (Ein SourceForge-Projekt zum Parsen von CSV-Daten).

Das XML-Serialisierungs-Framework sollte skalierbar sein, wenn Sie große (oder sehr große) CSV-Dateien in XML umwandeln möchten: Meine Empfehlung ist das Sun Java Streaming XML-Parser-Framework (siehe here ), das Pull-Parsing UND Serialisierung ermöglicht.


Ich weiß, dass Sie nach Java gefragt haben, aber das scheint mir eine Aufgabe zu sein, die für eine Skriptsprache gut geeignet ist. Hier ist eine schnelle (sehr einfache) Lösung, die in Groovy geschrieben wurde.

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 das folgende XML in 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>

Der Code analysiert jedoch sehr einfach (ohne Berücksichtigung von Anführungszeichen oder Kommas) und berücksichtigt keine fehlenden Daten.


Sie könnten XSLT verwenden . Google es und Sie werden ein paar Beispiele finden, zB CSV in XML. Wenn Sie XSLT verwenden , können Sie das XML in ein beliebiges Format konvertieren.


Soweit ich weiß, gibt es keine vorgefertigte Bibliothek, die dies für Sie erledigt. Für die Erstellung eines Tools, das in der Lage ist, von CSV in XML zu übersetzen, müssen Sie jedoch einen rohen CSV-Parser schreiben und JDOM (oder Ihre XML-Java-Bibliothek von JDOM) anschließen Wahl) mit etwas Klebercode.


Wie die anderen oben, kenne ich keinen Ein-Schritt-Weg, um das zu tun, aber wenn Sie bereit sind, sehr einfache externe Bibliotheken zu verwenden, würde ich vorschlagen:

OpenCsv zum Parsen von CSV (klein, einfach, zuverlässig und OpenCsv )

Xstream zum Parsen / Serialisieren von XML (sehr einfach zu verwenden und vollständig von Menschen lesbares XML zu erstellen)

Unter Verwendung der gleichen Beispieldaten wie oben würde der Code folgendermaßen 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();
        }
    }
}

Das folgende Ergebnis erzeugen: (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>




data-conversion