lib Java lub aplikacja do konwersji plików CSV do pliku XML?

głosy
95

Czy istnieje istniejących aplikacji lub biblioteki w Javie , która pozwoli mi przekonwertować CSVplik danych do XMLpliku?

Te XMLznaczniki będą dostarczane przez ewentualnie pierwszy rząd zawiera nagłówki kolumn.

Utwórz 01/08/2008 o 17:08
źródło użytkownik
W innych językach...                            


16 odpowiedzi

głosy
3

Może to być zbyt podstawowe lub ograniczone roztworu, ale nie można zrobić String.split()na każdej linii pliku, pamiętając tablicę wyniku pierwszej linii do generowania pliku XML, a tylko pluć danych tablicowych każda linia jest się z właściwym XML elementy dopełnienie każdej iteracji pętli?

Odpowiedział 01/08/2008 o 17:31
źródło użytkownik

głosy
60

Może to może pomóc: JSefa

można odczytać pliku CSV z tego narzędzia i szeregować je do XML.

Odpowiedział 01/08/2008 o 19:51
źródło użytkownik

głosy
13

Nie rozumiem, dlaczego chcesz to zrobić. To brzmi prawie jak kodowanie kulty cargo.

Konwersja pliku CSV do XML nie dodaje żadnej wartości. Program jest już odczytu pliku CSV, więc twierdząc, że trzeba XML nie działa.

Z drugiej strony, czytając plik CSV, robiąc coś z wartościami, a następnie szeregowania XML ma sens (dobrze, jak za pomocą XML może mieć sens ...;)), ale to podobno już mają możliwość szeregowania do XML.

Odpowiedział 01/08/2008 o 20:21
źródło użytkownik

głosy
7

O ile mi wiadomo, nie ma gotowej biblioteki to zrobić dla Ciebie, ale produkujących narzędzia zdolnego do tłumaczenia z CSV do XML powinny jedynie wymagać, aby napisać parser surowy CSV i zahaczyć JDOM (lub XML Java biblioteki wybór) z kodem kleju.

Odpowiedział 02/08/2008 o 20:06
źródło użytkownik

głosy
7

Nie ma nic, co wiem, że można to zrobić bez przynajmniej pisanie trochę kodu ... Trzeba będzie 2 oddzielne biblioteki:

  • Ramy CSV Parser
  • Ram serializacji XML

CSV parser polecam (chyba, że ​​chcesz mieć trochę zabawy do pisania własnych CSV Parser) jest OpenCSV (A SourceForge Project do analizowania danych CSV)

Serializacji XML ramowa powinna być czymś, co można skalować w przypadku, gdy chcesz przekształcić dużą (lub ogromny) plik CSV do XML: Moja rekomendacja jest Sun Java Streaming XML Parser Framework (patrz tutaj ), który pozwala wyciągnąć-parsowanie i serializacji.

Odpowiedział 04/08/2008 o 02:07
źródło użytkownik

głosy
24

Wiem, że poprosił o Javie, ale to uderza mnie jako zadanie dobrze nadaje się do języka skryptowego. Oto szybki (bardzo prosty) rozwiązanie napisane w 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])
            }
        }
    }
}

Pisze następujące XML do 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>

Jednak kod robi bardzo prosty parsowanie (nie biorąc pod uwagę cytowany lub uciekły przecinków) i nie uwzględnia możliwych danych nieobecnych.

Odpowiedział 09/08/2008 o 12:06
źródło użytkownik

głosy
15

To rozwiązanie nie wymaga CSV lub XML i bibliotek, wiem, że nie obsługuje żadnych niedozwolonych znaków i zagadnień kodowania, ale może być zainteresowany w nim, a także, o ile Twój wkład CSV nie łamie powyższe zasady.

Uwaga: Nie należy stosować tego kodu, chyba że wiesz co robisz, albo nie mieć szansę na wykorzystanie dalszy bibliotekę (możliwe w niektórych projektach biurokratycznych) ... Użyj StringBuffer dla starszych środowiskach wykonawczych ...

Więc zaczynamy:

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 wejściowy (skradziony z innego odpowiedź na tej stronie):

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

Wynikiem:

<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>
Odpowiedział 22/08/2008 o 00:17
źródło użytkownik

głosy
45

Jak wyżej inni, ja nie znam żadnego jednoetapowy sposób to zrobić, ale jeśli są gotowe do użycia bardzo proste zewnętrznych bibliotek, chciałbym zaproponować:

OpenCsv do analizowania CSV (mały, prosty, niezawodny i łatwy w użyciu)

Xstream do analizowania / serializacji XML (bardzo łatwy w użyciu, a także stworzenie w pełni czytelnej XML)

Stosując te same dane przykładowe jak wyżej, kod będzie wyglądać następująco:

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

Produkujących następujący wynik: (Xstream umożliwia bardzo precyzyjne dostrojenie wyniku ...)

<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>
Odpowiedział 10/09/2008 o 08:06
źródło użytkownik

głosy
3

Dla części CSV, można użyć moją małą bibliotekę open source

Odpowiedział 16/09/2008 o 17:07
źródło użytkownik

głosy
17

Mam ram opensource do pracy z CSV i płaskich plików w ogóle. Może warto przyjrzeć: JFileHelpers .

Z tego zestawu narzędzi można napisać kod za pomocą ziaren, takich jak:

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

a potem po prostu analizować pliki tekstowe za pomocą:

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

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

I będziesz miał kolekcję analizowanych obiektów.

Nadzieję, że pomoże!

Odpowiedział 28/09/2008 o 00:43
źródło użytkownik

głosy
8

Jest też dobra biblioteka ServingXML Daniel Parker, który jest w stanie konwertować prawie każdy zwykły format tekstowy XML iz powrotem.

Przykład Twoim przypadku można znaleźć tutaj : Używa nagłówek pola w pliku CSV jako nazwy elementu XML.

Odpowiedział 30/09/2008 o 22:22
źródło użytkownik

głosy
14

Można to zrobić za pomocą Groovy wyjątkowo łatwo, a kod jest bardzo czytelny.

Zasadniczo, zmienna tekst zostanie zapisany do contacts.xmldla każdej linii w contactData.csv, a tablica pól zawiera każdą kolumnę.

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>"""
}
Odpowiedział 02/10/2008 o 07:08
źródło użytkownik

głosy
11

Można użyć XSLT . Google a znajdziesz kilka przykładów, np CSV do XML Jeśli używasz XSLT można następnie przekształcić XML do formatu cokolwiek chcesz.

Odpowiedział 16/10/2008 o 15:33
źródło użytkownik

głosy
14

Największą różnicą jest to, że JSefa przynosi to, że może szeregować swoje obiekty Java do plików CSV / XML / etc i może deserializowania powrotem do obiektów Java. I jest napędzany przez adnotacje co daje dużą kontrolę nad wyjściem.

JFileHelpers również wygląda interesująco.

Odpowiedział 11/08/2010 o 06:49
źródło użytkownik

głosy
3

Miałem ten sam problem i potrzebne aplikacji do konwersji pliku CSV do pliku XML dla jednego z moich projektów, ale nie znaleźliśmy nic za darmo i wystarczająco dobre w internecie, więc kodowane własną aplikację Java Swing CSVtoXML.

Jest ona dostępna z mojej strony TUTAJ . Nadzieję, że to pomoże.

Jeśli nie, można łatwo kodować własne jak ja; Kod źródłowy jest wewnątrz pliku jar tak go zmodyfikować, jak trzeba, jeśli nie wypełnia swoje wymagania.

Odpowiedział 16/04/2014 o 01:12
źródło użytkownik

głosy
4

Jackson rodzina procesor ma bazami dla wielu formatów danych, a nie tylko JSON. Obejmuje to zarówno XML ( https://github.com/FasterXML/jackson-dataformat-xml ) i CSV ( https://github.com/FasterXML/jackson-dataformat-csv/ ) backendów.

Konwersja będzie polegać na czytanie wejście z CSV backend, pisać za pomocą XML backend. Jest to najłatwiej zrobić, jeśli masz (lub można zdefiniować) POJO dla per-rzędu (CSV) wpisów. To nie jest ścisły wymóg, zgodnie z treścią CSV mogą być odczytywane „bez typu” jak również (ciąg Stringtablic), ale wymaga nieco więcej pracy na wyjściu XML.

Na stronie XML, musisz obiektu głównego opakowania na potrzeby tablicy lub Listobiektów do serializacji.

Odpowiedział 29/04/2015 o 20:01
źródło użytkownik

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