Vra

Is daar 'n bestaande toepassing of biblioteek in Java wat my sal toelaat om a CSV data lêer na XML lêer?

Die XML etikette sal verskaf word deur moontlik die eerste ry wat kolomopskrifte bevat.

Was dit nuttig?

Oplossing

Miskien kan dit help: JSefa

U kan CSV-lêer met hierdie instrument lees en dit na XML serialiseer.

Ander wenke

Soos die ander hierbo, ken ek geen eenstap-manier om dit te doen nie, maar as jy gereed is om baie eenvoudige eksterne biblioteke te gebruik, sal ek voorstel:

OpenCsv vir die ontleding van CSV (klein, eenvoudig, betroubaar en maklik om te gebruik)

Xstream om XML te ontleed / te serialiseer (baie baie maklik om te gebruik, en skep ten volle mens-leesbare xml)

Deur dieselfde voorbeelddata as hierbo te gebruik, sal kode soos volg lyk:

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

Produseer die volgende resultaat:(Xstream laat baie fyn tuning van die resultaat toe...)

<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>

Ek weet jy het vir Java gevra, maar dit lyk my as 'n taak wat goed geskik is vir 'n skriftaal.Hier is 'n vinnige (baie eenvoudige) oplossing geskryf in Groovy.

toets.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])
            }
        }
    }
}

Skryf die volgende XML na 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>

Die kode doen egter baie eenvoudige ontleding (met nie aanhalingstekens of ontsnapte kommas in ag nie) en dit maak nie rekening met moontlike afwesige data nie.

Ek het 'n oopbronraamwerk om met CSV en plat lêers in die algemeen te werk.Miskien is dit die moeite werd om te kyk: JFileHelpers.

Met daardie gereedskapstel kan jy kode skryf deur boontjies te gebruik, soos:

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

en ontleed dan net jou tekslêers met behulp van:

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

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

En jy sal 'n versameling van ontleed voorwerpe hê.

Hoop dit help!

Hierdie oplossing het geen CSV- of XML-biblioteke nodig nie en, ek weet, dit hanteer geen onwettige karakters en enkoderingskwessies nie, maar jy sal dalk ook daarin belangstel, mits jou CSV-invoer nie die bogenoemde reëls oortree nie.

Aandag: Jy moet nie hierdie kode gebruik tensy jy weet wat jy doen of nie die kans het om 'n verdere biblioteek te gebruik nie (moontlik in sommige burokratiese projekte)...Gebruik 'n StringBuffer vir ouer Runtime-omgewings...

So hier gaan ons:

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 invoer toets.csv (gesteel uit 'n ander antwoord op hierdie bladsy):

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 gevolglike uitset:

<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>

Die groot verskil is dit JSefa bring in, is dat dit jou Java-voorwerpe kan serialiseer na CSV/XML/ens-lêers en kan terugdeserialiseer na Java-voorwerpe.En dit word aangedryf deur aantekeninge wat jou baie beheer oor die uitset gee.

JFileHelpers lyk ook interessant.

Ek verstaan ​​nie hoekom jy dit sou wou doen nie.Dit klink amper soos vragkultuskodering.

Die omskakeling van 'n CSV-lêer na XML voeg geen waarde toe nie.Jou program lees reeds die CSV-lêer, so om te argumenteer dat jy XML nodig het, werk nie.

Aan die ander kant, lees die CSV-lêer, doen iets met die waardes, en dan serialisering na XML maak sin (wel, soveel as die gebruik van XML kan sin maak ...;)), maar jy sou vermoedelik reeds 'n manier hê om na XML te serialiseer.

Jy kan dit buitengewoon maklik doen met Groovy, en die kode is baie leesbaar.

Basies sal daar na die teksveranderlike geskryf word contacts.xml vir elke reël in die contactData.csv, en die velde-skikking bevat elke kolom.

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>"""
}

Jy kan gebruik XSLT.Google dit en jy sal 'n paar voorbeelde kry bv. CSV na XMLAs jy gebruik XSLT jy kan dan die XML omskakel na watter formaat jy ook al wil hê.

Daar is ook goeie biblioteek Diens XML deur Daniel Parker, wat bykans enige gewone teksformaat na XML en terug kan omskakel.

Die voorbeeld vir jou geval kan gevind word hier:Dit gebruik veldopskrif in CSV-lêer as die XML-elementnaam.

Daar is niks waarvan ek weet wat dit kan doen sonder dat jy ten minste 'n bietjie kode skryf nie...Jy benodig 2 aparte biblioteek:

  • 'n CSV-ontleder-raamwerk
  • 'n XML-serialiseringsraamwerk

Die CSV-ontleder wat ek sou aanbeveel (tensy jy 'n bietjie pret wil hê om jou eie CSV-ontleder te skryf) is OpenCSV ('n SourceForge-projek vir die ontleding van CSV-data)

Die XML-serialiseringsraamwerk behoort iets te wees wat kan skaal indien jy groot (of groot) CSV-lêer na XML wil transformeer:My aanbeveling is die Sun Java Streaming XML Parser Framework (Sien hier) wat trek-ontleding EN serialisering moontlik maak.

Sover ek weet, is daar geen klaargemaakte biblioteek om dit vir jou te doen nie, maar om 'n instrument te produseer wat van CSV na XML kan vertaal, moet net vereis dat jy 'n rowwe CSV-ontleder skryf en JDOM (of jou XML Java-biblioteek van keuse) met 'n paar gomkode.

Jackson-verwerkerfamilie het backends vir veelvuldige dataformate, nie net JSON nie.Dit sluit beide XML (https://github.com/FasterXML/jackson-dataformat-xml) en CSV (https://github.com/FasterXML/jackson-dataformat-csv/) backends.

Omskakeling sal staatmaak op leesinsette met CSV-rugsteun, skryf met behulp van XML-agterkant.Dit is die maklikste om te doen as jy 'n POJO vir per-ry (CSV) inskrywings het (of kan definieer).Dit is nie 'n streng vereiste nie, aangesien inhoud van CSV ook "ongetik" gelees kan word ('n volgorde van String skikkings), maar vereis bietjie meer werk op XML-uitvoer.

Vir die XML-kant sal jy 'n omhulselwortelvoorwerp nodig hê om skikking of List van voorwerpe om te serialiseer.

Dit is dalk te basies of te beperk van 'n oplossing, maar kon jy nie 'n doen nie String.split() op elke reël van die lêer, onthou die resultaat-skikking van die eerste reël om die XML te genereer, en spoeg net elke reël se skikking-data uit met die regte XML-elemente wat elke iterasie van 'n lus opvul?

Ek het dieselfde probleem gehad en het 'n toepassing nodig gehad om 'n CSV-lêer na 'n XML-lêer om te skakel vir een van my projekte, maar het niks gratis en goed genoeg op die net gevind nie, so ek het my eie Java Swing CSVtoXML-toepassing gekodeer.

Dit is beskikbaar vanaf my webwerf HIER.Hoop dit sal jou help.

Indien nie, kan jy maklik jou eie kodeer soos ek gedoen het;Die bronkode is binne die jar-lêer, so wysig dit soos jy nodig het as dit nie aan jou vereiste voldoen nie.

Vir die CSV-deel, kan jy gebruik my klein oopbron-biblioteek

Gelisensieer onder: CC-BY-SA met toeskrywing
Nie verbonde aan StackOverflow
scroll top