Er det et eksisterende program eller bibliotek i Java som vil tillate meg å konvertere en CSV
datafil til XML
fil?
De XML
koder vil bli gitt gjennom muligens den første raden som inneholder kolonneoverskriftene.
Er det et eksisterende program eller bibliotek i Java som vil tillate meg å konvertere en CSV
datafil til XML
fil?
De XML
koder vil bli gitt gjennom muligens den første raden som inneholder kolonneoverskriftene.
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?
Kanskje dette kan hjelpe: JSefa
Du kan lese CSV-fil med dette verktøyet og serial det til XML.
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.
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.
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:
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.
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.
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>
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>
For CSV del, kan du bruke min lille åpen kildekode bibliotek
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!
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.
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.xml
for 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>"""
}
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.
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.
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.
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 String
arrays), men krever litt mer arbeid på XML utgang.
For XML side, ville du trenger en wrapper rotobjektet å inneholde matrise eller List
objekter til serial.