Java lib lub aplikacja do konwersji pliku CSV na XML?

Czy istnieje jakaś aplikacja lub biblioteka W Java, która pozwoli mi przekonwertować plik CSV Na plik XML?

Znaczniki XML będą dostarczane przez prawdopodobnie pierwszy wiersz zawierający nagłówki kolumn.

Author: Mohit, 2008-08-01

16 answers

Może to pomoże: JSefa

Możesz odczytać plik CSV za pomocą tego narzędzia i serializować go do XML.

 62
Author: svrist,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-07 10:36:04

Podobnie jak pozostałe powyżej, nie znam żadnego jednoetapowego sposobu, aby to zrobić, ale jeśli jesteś gotowy do korzystania z bardzo prostych bibliotek zewnętrznych, proponuję:

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

Xstream to parse / serialize XML (bardzo bardzo łatwy w użyciu i tworzenie w pełni czytelnego xml)

Używając tych samych przykładowych danych jak powyżej, kod wyglądałby 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();
        }
    }
}

Daje następujący wynik: (Xstream pozwala bardzo dobrze strojenie 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>
 46
Author: Laurent K,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-27 06:06:59

Wiem, że prosiłeś o Javę, ale wydaje mi się, że jest to zadanie dobrze dopasowane do języka skryptowego. Oto szybkie (bardzo proste) 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])
            }
        }
    }
}

Zapisuje następujący 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 wykonuje bardzo proste parsowanie (nie biorąc pod uwagę cytowanych lub unikalnych przecinków) i nie uwzględnia ewentualnych nieobecnych danych.

 25
Author: Anthony Cramp,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-07 10:37:12

Mam opensource framework do pracy z plikami CSV i płaskimi w ogóle. Może warto poszukać: JFileHelpers .

Za pomocą tego zestawu narzędzi możesz pisać kod używając beans, np:

@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 następnie po prostu przeanalizuj swoje pliki tekstowe używając:

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ę parsowanych obiektów.

Mam nadzieję, że to pomoże!
 18
Author: kolrie,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-07 18:56:09

To rozwiązanie nie wymaga żadnych bibliotek CSV ani XML i Wiem, że nie obsługuje żadnych nielegalnych znaków i problemów z kodowaniem, ale możesz być nim zainteresowany, pod warunkiem, że twoje wejście CSV nie łamie wyżej wymienionych reguł.

Uwaga: nie powinieneś używać tego kodu, chyba że wiesz, co robisz lub nie masz możliwości korzystania z dalszej biblioteki (możliwe w niektórych biurokratycznych projektach)... Użyj StringBuffer dla starszych środowisk 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 wejściowy.csv (skradziony z innej odpowiedzi 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

Wynik:

<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>
 17
Author: Martin Klinke,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-02 14:14:39

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

Konwersja pliku CSV na XML nie dodaje żadnej wartości. Twój program już czyta plik CSV, więc argumentowanie, że potrzebujesz XML nie działa.

Z drugiej strony, czytanie pliku CSV, Robienie czegoś z wartościami, a następnie serializowanie do XML ma sens (cóż, tak samo jak używanie XML może mieć sens... ;)) ale podobno masz już środki na serializacja do XML.

 15
Author: Ryan Fox,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-01 19:21:57

Duża różnica polega na tym, że JSefa może serializować obiekty java do plików CSV/XML/etc i może deserializować z powrotem do obiektów java. I jest napędzany przez adnotacje, które dają dużą kontrolę nad wyjściem.

JFileHelpers również wygląda ciekawie.

 15
Author: James Selvakumar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-07 10:40:32

Możesz to zrobić wyjątkowo łatwo używając Groovy, a kod jest bardzo czytelny.

Zasadniczo zmienna tekstowa będzie zapisywana do contacts.xml dla każdej linii w contactData.csv, a tablica fields 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>"""
}
 15
Author: abarax,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-10 20:04:49

Możesz użyć XSLT . Google go i znajdziesz kilka przykładów np. CSV do XML Jeśli używasz XSLT możesz następnie przekonwertować XML na dowolny format.

 12
Author: Simmo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-07 10:41:10

Istnieje również dobra biblioteka ServingXML autorstwa Daniela Parkera, która jest w stanie przekonwertować prawie każdy zwykły format tekstowy na XML i z powrotem.

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

 8
Author: Lukáš Rampa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-07 10:45:43

Z tego, co wiem, nie ma gotowej biblioteki, która zrobiłaby to za ciebie, ale wyprodukowanie narzędzia zdolnego do tłumaczenia z CSV na XML powinno wymagać tylko napisania surowego parsera CSV i podłączenia JDOM (lub wybranej biblioteki Javy XML) z jakimś kodem kleju.

 8
Author: Matt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-10 20:56:11

Nic o tym Nie wiem, ale bez ciebie przynajmniej napisanie odrobiny kodu... Będziesz potrzebował 2 osobnej biblioteki:

  • Framework parsera CSV
  • Framework serializacji XML

Parser CSV polecam (chyba, że chcesz mieć trochę zabawy, aby napisać własny Parser CSV) to OpenCSV (projekt SourceForge do parsowania danych CSV)

Framework serializacji XML powinien być czymś, co może być skalowane w przypadku, gdy chcesz przekształć duży (lub ogromny) plik CSV na XML: moim zaleceniem jest Sun Java Streaming XML Parser Framework (zobacz tutaj), który umożliwia pull-parsing i serializację.

 7
Author: Claude Houle,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-26 00:02:54

To może być zbyt proste lub ograniczone rozwiązanie, ale nie mógłbyś zrobić String.split() na każdej linii pliku, pamiętając tablicę wyników pierwszej linii do generowania XML, i po prostu wypluć dane tablicy każdej linii z odpowiednimi elementami XML wypełniającymi każdą iterację pętli?

 4
Author: saint_groceon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-26 00:02:16

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

Konwersja polegałaby na odczycie danych wejściowych za pomocą backendu CSV, zapisywaniu za pomocą backendu XML. Jest to najprostsze do zrobienia, jeśli masz (lub możesz zdefiniować) POJO dla wpisów per-row (CSV). Nie jest to ścisły wymóg, ponieważ zawartość z pliku CSV może być odczyt "untyped" (Sekwencja tablic String), ale wymaga nieco więcej pracy nad wyjściem XML.

Po stronie XML potrzebny będzie główny obiekt wrapper, który będzie zawierał tablicę lub List obiektów do serializacji.

 4
Author: StaxMan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-29 20:01:12

Miałem ten sam problem i potrzebowałem aplikacji do konwersji pliku CSV na plik XML dla jednego z moich projektów, ale nie znalazłem nic darmowego i wystarczająco dobrego w sieci, więc zakodowałem własną aplikację Java Swing CSVtoXML.

Jest dostępny na mojej stronie TUTAJ . Mam nadzieję, że ci pomoże.

Jeśli nie, możesz łatwo zakodować swój własny kod, tak jak ja; kod źródłowy znajduje się w pliku jar, więc zmodyfikuj go według potrzeb, Jeśli nie spełnia twoich wymagań.

 3
Author: Ibrabel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-18 11:14:48

Do części CSV możesz użyć mojej małej biblioteki open source

 3
Author: Arne Burmeister,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-20 19:07:38