Java lib eller app for å konvertere CSV til XML-fil?

stemmer
99

Er det et eksisterende program eller bibliotek i Java som vil tillate meg å konvertere en CSVdatafil til XMLfil?

De XMLkoder vil bli gitt gjennom muligens den første raden som inneholder kolonneoverskriftene.

Publisert på 01/08/2008 klokken 16:08
kilden bruker
På andre språk...                            


16 svar

stemmer
62

Kanskje dette kan hjelpe: JSefa

Du kan lese CSV-fil med dette verktøyet og serial det til XML.

Svarte 01/08/2008 kl. 18:51
kilden bruker

stemmer
46

Som de andre ovennevnte, jeg vet ikke hvilken som helst ett-trinns måte å gjøre det, men hvis du er klar til å bruke svært enkle eksterne biblioteker, vil jeg foreslå:

OpenCsv for parsing CSV (liten, enkel, pålitelig og lett å bruke)

Xstream å analysere / serial XML (meget meget enkel å bruke, og skaper fullt ut lesbar xml)

Bruke samme eksempel data som ovenfor, ville koden se slik ut:

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

Produserer følgende resultat: (Xstream gjør veldig finjustering av resultatet ...)

<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>
Svarte 10/09/2008 kl. 07:06
kilden bruker

stemmer
25

Jeg vet at du ba om Java, men dette slår meg som en oppgave godt egnet til et skriptspråk. Her er en rask (veldig enkel) løsning skrevet i 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])
            }
        }
    }
}

Skriver følgende XML til 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>

Men gjør koden veldig enkel parsing (ikke hensyntatt sitert eller rømt komma), og det ikke står for mulige fraværende data.

Svarte 09/08/2008 kl. 11:06
kilden bruker

stemmer
18

Jeg har en opensource rammeverk for å arbeide med CSV og flate filer generelt. Kanskje det er verdt å se: JFileHelpers .

Med det verktøysettet kan du skrive koden ved hjelp av bønner, som:

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

og så bare analysere tekstfiler ved hjelp av:

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

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

Og vil du ha en samling av analyseres stedene.

Håper det hjelper!

Svarte 27/09/2008 kl. 23:43
kilden bruker

stemmer
17

Denne løsningen trenger ikke noen CSV eller XML biblioteker, og jeg vet det ikke håndterer ulovlige tegn og koding problemer, men du kan være interessert i det også, forutsatt at CSV innspill ikke bryter de ovennevnte regler.

OBS: Du bør ikke bruke denne koden med mindre du vet hva du gjør eller ikke har muligheten til å bruke en ytterligere bibliotek (mulig i noen byråkratiske prosjekter) ... Bruk en Stringbuffer for eldre Runtime Environment ...

Så her går vi:

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

Inngangs test.csv (stjålet fra et annet svar på denne siden):

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

Den resulterende utgangs:

<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>
Svarte 21/08/2008 kl. 23:17
kilden bruker

stemmer
15

Den store forskjellen er at JSefa bringer inn er at det kan serienummer java objektene til CSV / XML / etc filer og kan deserialize tilbake til java stedene. Og det er drevet av merknader som gir deg mye kontroll over produksjonen.

JFileHelpers ser også interessant.

Svarte 11/08/2010 kl. 05:49
kilden bruker

stemmer
15

Du kan gjøre dette svært enkelt ved hjelp av Groovy, og koden er svært lesbar.

I utgangspunktet vil tekstvariabelen bli skrevet til contacts.xmlfor hver linje i contactData.csv, og det felt matrisen inneholder hver kolonne.

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>"""
}
Svarte 02/10/2008 kl. 06:08
kilden bruker

stemmer
15

Jeg forstår ikke hvorfor du ønsker å gjøre dette. Det høres nesten ut som cargo-kult koding.

Konvertere en CSV-fil til XML legger ikke noen verdi. Programmet er allerede lese CSV-filen, så hevder at du trenger XML virker ikke.

På den annen side, lese CSV-filen, gjør noe med verdiene, og deretter seriefunksjon til XML gir mening (vel så mye som ved hjelp av XML kan være fornuftig ...;)), men du ville visstnok allerede ha et middel seriefunksjon til XML.

Svarte 01/08/2008 kl. 19:21
kilden bruker

stemmer
12

Du kan bruke XSLT . Google det og du vil finne noen eksempler f.eks CSV til XML Hvis du bruker XSLT du kan deretter konvertere XML til det formatet du ønsker.

Svarte 16/10/2008 kl. 14:33
kilden bruker

stemmer
8

Det er også godt bibliotek ServingXML av Daniel Parker, som er i stand til å konvertere nesten alle rent tekstformat for XML og tilbake.

Eksempelet for ditt tilfelle kan bli funnet her : Den bruker overskriften feltet i CSV-filen som XML element navn.

Svarte 30/09/2008 kl. 21:22
kilden bruker

stemmer
8

Så vidt jeg vet, er det ingen ferdige bibliotek for å gjøre dette for deg, men å produsere et verktøy som kan oversette fra CSV til XML bør bare krever at du å skrive en grov CSV parser og hekte JDOM (eller XML Java bibliotek av valget) med litt lim kode.

Svarte 02/08/2008 kl. 19:06
kilden bruker

stemmer
7

Det er ingenting jeg vet om som kan gjøre dette uten at du i det minste skrive en liten bit av koden ... Du trenger to separate bibliotek:

  • En CSV parser Framework
  • En XML-serialisering Work

CSV-parseren vil jeg anbefale (med mindre du ønsker å ha litt moro å skrive din egen CSV parser) er OpenCSV (A SourceForge prosjekt for analysering av CSV data)

XML-serialisering Work bør være noe som kan skaleres i tilfelle du ønsker å transformere store (eller stor) CSV-filen til XML: Min anbefaling er Sun Java Streaming XML parser Framework (se her ) som gjør pull-parsing og serialisering.

Svarte 04/08/2008 kl. 01:07
kilden bruker

stemmer
4

Jackson-prosessor familie har backends for flere dataformater, ikke bare JSON. Dette inkluderer både XML ( https://github.com/FasterXML/jackson-dataformat-xml ) og CSV ( https://github.com/FasterXML/jackson-dataformat-csv/ ) backends.

Konvertering ville stole på lesing inngang med CSV backend, skrive ved hjelp av XML backend. Dette er lettest å gjøre hvis du har (eller kan definere) en POJO for per rad (CSV) oppføringer. Dette er ikke et strengt krav, som innhold fra CSV kan leses "utypet" i tillegg (en sekvens av Stringarrays), men krever litt mer arbeid på XML utgang.

For XML side, ville du trenger en wrapper rotobjektet å inneholde matrise eller Listobjekter til serial.

Svarte 29/04/2015 kl. 20:01
kilden bruker

stemmer
4

Dette kan være for grunnleggende eller begrenses av en løsning, men kan ikke du gjøre String.split()på hver linje i filen, husker resultatet utvalg av første linje for å generere XML, og bare spytte hver linje fylking data ut med riktig XML elementer padding hver iterasjon av en løkke?

Svarte 01/08/2008 kl. 16:31
kilden bruker

stemmer
3

Jeg hadde det samme problemet, og trengte et program for å konvertere en CSV-fil til en XML-fil for en av mine prosjekter, men fant ikke noe gratis og god nok på nettet, så jeg kodet min egen Java Swing CSVtoXML søknad.

Den er tilgjengelig fra min hjemmeside HER . Håper det vil hjelpe deg.

Hvis ikke, kan du enkelt koden din egen som jeg gjorde; Kildekoden er inne i jar-filen så endrer det som du trenger hvis det ikke fyller kravet.

Svarte 16/04/2014 kl. 00:12
kilden bruker

stemmer
3

For CSV del, kan du bruke min lille åpen kildekode bibliotek

Svarte 16/09/2008 kl. 16:07
kilden bruker

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