DISABILITARE ADBLOCK

ADBlock sta bloccando alcuni contenuti del sito

ADBlock errore
risultati trovati: 

DOMANDA

Esiste un'applicazione o libreria esistente in Java che mi permetterà di convertire un file di dati CSV in file XML ?

I tag XML verrebbero forniti attraverso possibilmente la prima riga contenente le intestazioni di colonna.

SOLUZIONE

Forse questo potrebbe aiutare: JSefa

Puoi leggere il file CSV con questo strumento e serializzarlo su XML.

Se ti va lasciaci una tua opinione

L'articolo ti è stato utile ed è tradotto correttamente?

ALTRI SUGGERIMENTI

Come gli altri sopra, non conosco alcun modo per farlo, ma se sei pronto per usare librerie esterne molto semplici, suggerirei:

OpenCsv per l'analisi di CSV (piccolo, semplice, affidabile e facile da usare)

Xstream per analizzare / serializzare XML (molto molto facile da usare e creare xml completamente leggibili dall'uomo)

Utilizzando gli stessi dati di esempio di cui sopra, il codice sarebbe simile a:

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

Producendo il seguente risultato: (Xstream consente una regolazione molto precisa del risultato ...)

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

So che hai chiesto Java, ma questo mi sembra un compito adatto a un linguaggio di scripting. Ecco una soluzione rapida (molto semplice) scritta in 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])
            }
        }
    }
}

Scrive il seguente XML su 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>

Tuttavia, il codice esegue un analisi molto semplice (non tiene conto delle virgolette tra virgolette o di escape) e non tiene conto di possibili dati assenti.

Ho un framework opensource per lavorare con CSV e file flat in generale. Forse vale la pena cercare: JFileHelpers .

Con quel toolkit puoi scrivere codice usando i bean, come:

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

e quindi analizza i tuoi file di testo usando:

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

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

E avrai una raccolta di oggetti analizzati.

Spero che ti aiuti!

Questa soluzione non ha bisogno di alcuna libreria CSV o XML e, lo so, non gestisce caratteri illegali e problemi di codifica, ma potresti essere interessato anche a essa, a condizione che il tuo input CSV non infranga le regole sopra menzionate .

Attenzione: non dovresti usare questo codice se non sai cosa fai o non hai la possibilità di usare un'ulteriore libreria (possibile in alcuni progetti burocratici) ... Usa un StringBuffer per ambienti di runtime precedenti ...

Quindi eccoci qui:

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

L'input test.csv (rubato da un'altra risposta in questa pagina):

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

L'output risultante:

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

La grande differenza è che JSefa è che può serializzare i tuoi oggetti Java su CSV / XML / etc e può deserializzare nuovamente gli oggetti Java. Ed è guidato da annotazioni che ti danno molto controllo sull'output.

Anche JFileHelpers sembra interessante.

Non capisco perché vorresti farlo. Sembra quasi un codice di culto per il carico.

La conversione di un file CSV in XML non aggiunge alcun valore. Il tuo programma sta già leggendo il file CSV, quindi sostenere che hai bisogno di XML non funziona.

D'altra parte, leggere il file CSV, fare qualcosa con i valori e quindi serializzare su XML ha senso (beh, anche se usare XML può avere senso ...;) ) ma presumibilmente avresti già un mezzo per serializzare in XML.

Puoi farlo eccezionalmente facilmente usando Groovy e il codice è molto leggibile.

Fondamentalmente, la variabile di testo verrà scritta in contatti.xml per ogni riga in contactData.csv e l'array dei campi contiene ogni colonna.

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

Puoi utilizzare XSLT . Cercalo su Google e troverai alcuni esempi, ad es. CSV in XML Se usi XSLT puoi quindi convertire l'XML nel formato che desideri.

Esiste anche una buona libreria ServingXML di Daniel Parker, che è in grado di convertire quasi qualsiasi formato di testo in XML e ritorno.

L'esempio del tuo caso può essere trovato qui : utilizza l'intestazione di campo nel file CSV come nome dell'elemento XML.

Non so nulla che possa fare questo senza che tu scriva almeno un po 'di codice ... Avrai bisogno di 2 librerie separate:

  • Un CSV Parser Framework
  • Un framework di serializzazione XML

Il parser CSV che consiglierei (a meno che tu non voglia divertirti un po 'a scrivere il tuo parser CSV) è OpenCSV (un progetto SourceForge per l'analisi dei dati CSV)

Il XML Serialization Framework dovrebbe essere qualcosa che può essere ridimensionato nel caso in cui si desideri trasformare un file CSV di grandi dimensioni (o enorme) in XML: la mia raccomandazione è il Sun Parser Framework di streaming Java Sun (Vedi qui ) che consente l'analisi pull e la serializzazione.

Per quanto ne so, non esiste una libreria pronta per farlo per te, ma produrre uno strumento in grado di tradurre da CSV a XML dovrebbe richiedere solo di scrivere un parser CSV grezzo e collegare JDOM (o il tuo XML Libreria Java preferita) con un po 'di codice colla.

La famiglia di processori Jackson ha backend per più formati di dati, non solo JSON. Ciò include sia XML ( https://github.com/FasterXML/jackson-dataformat-xml) e CSV ( https://github.com/FasterXML/jackson-dataformat-csv/ ) backend.

La conversione si baserebbe sulla lettura dell'input con il back-end CSV, la scrittura utilizzando il back-end XML. Questo è più facile da fare se si dispone (o è possibile definire) un POJO per voci per riga (CSV). Questo non è un requisito rigoroso, in quanto il contenuto di CSV può essere letto "non tipizzato". anche (una sequenza di matrici String ), ma richiede un po 'più di lavoro sull'output XML.

Per il lato XML, è necessario un oggetto root wrapper per contenere array o List di oggetti da serializzare.

Questa potrebbe essere una soluzione troppo semplice o limitata, ma non potresti fare un String.split () su ciascuna riga del file, ricordando l'array dei risultati della prima riga in generare l'XML e sputare semplicemente i dati dell'array di ogni riga con gli elementi XML appropriati che riempiono ogni iterazione di un ciclo?

Ho avuto lo stesso problema e avevo bisogno di un'applicazione per convertire un file CSV in un file XML per uno dei miei progetti, ma non ho trovato nulla di gratuito e abbastanza buono in rete, quindi ho codificato la mia applicazione Java Swing CSVtoXML .

È disponibile dal mio sito web QUI . Spero che ti possa aiutare.

In caso contrario, puoi facilmente codificare il tuo come ho fatto io; Il codice sorgente è all'interno del file jar, quindi modificalo secondo le tue necessità se non soddisfa i tuoi requisiti.

Per la parte CSV, puoi utilizzare la mia piccola libreria open source

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow