Java lib ou application pour convertir CSV en fichier XML?


Existe-t-il une application ou une bibliothèque existante dans Java qui me permettra de convertir un fichier de données CSV en fichier XML?

Les balises XML seraient fournies via éventuellement la première ligne contenant les en-têtes de colonne.

Author: Mohit, 2008-08-01

16 answers

Peut-être que cela pourrait aider: JSefa

Vous pouvez lire le fichier CSV avec cet outil et le sérialiser en XML.

 62
Author: svrist, 2013-02-07 10:36:04

Comme les autres ci-dessus, je ne connais aucun moyen en une étape de le faire, mais si vous êtes prêt à utiliser des bibliothèques externes très simples, je suggérerais:

OpenCsv pour analyser CSV (petit, simple, fiable et facile à utiliser)

Xstream pour analyser / sérialiser XML (très très facile à utiliser, et créer un XML entièrement lisible par l'homme)

En utilisant les mêmes exemples de données que ci-dessus, le code ressemblerait à:

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

Produisant le résultat suivant: (Xstream permet très bien réglage du résultat...)

<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, 2016-01-27 06:06:59

Je sais que vous avez demandé Java, mais cela me semble une tâche bien adaptée à un langage de script. Voici une solution rapide (très simple) écrite en 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])
            }
        }
    }
}

Écrit le XML suivant dans 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>

Cependant, le code effectue une analyse très simple (ne tenant pas compte des virgules entre guillemets ou échappées) et il ne tient pas compte des données absentes possibles.

 25
Author: Anthony Cramp, 2013-02-07 10:37:12

J'ai un framework opensource pour travailler avec des fichiers CSV et plats en général. Peut-être que cela vaut la peine de regarder: JFileHelpers.

Avec cette boîte à outils, vous pouvez écrire du code en utilisant des beans, comme:

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

Puis analysez simplement vos fichiers texte en utilisant:

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

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

Et vous aurez une collection d'objets analysés.

J'espère que ça aide!

 18
Author: kolrie, 2013-02-07 18:56:09

Cette solution n'a pas besoin de bibliothèques CSV ou XML et, je sais, elle ne gère aucun caractère illégal et aucun problème d'encodage, mais cela pourrait également vous intéresser, à condition que votre entrée CSV ne viole pas les règles mentionnées ci-dessus.

Attention: Vous ne devez pas utiliser ce code sauf si vous savez ce que vous faites ou si vous n'avez pas la possibilité d'utiliser une autre bibliothèque (possible dans certains projets bureaucratiques)... Utilisez un StringBuffer pour les anciens environnements d'exécution...

Donc nous y allons:

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

Le test d'entrée.csv (volé d'une autre réponse sur cette page):

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

La sortie résultante:

<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, 2015-11-02 14:14:39

Je ne comprends pas pourquoi vous voudriez faire cela. Cela ressemble presque au codage culte de la cargaison.

La conversion d'un fichier CSV en XML n'ajoute aucune valeur. Votre programme lit déjà le fichier CSV, donc faire valoir que vous avez besoin de XML ne fonctionne pas.

D'autre part, lire le fichier CSV, faire quelque chose avec les valeurs, puis sérialiser en XML a du sens (enfin, autant que l'utilisation de XML peut avoir du sens... ;)) mais vous auriez soi-disant déjà un moyen de sérialisation au format XML.

 15
Author: Ryan Fox, 2008-08-01 19:21:57

La grande différence est que JSefa apporte est qu'il peut sérialiser vos objets java en fichiers CSV/XML/etc et peut désérialiser en objets java. Et il est piloté par des annotations qui vous donne beaucoup de contrôle sur la sortie.

JFileHelpers semble également intéressant.

 15
Author: James Selvakumar, 2013-02-07 10:40:32

Vous pouvez le faire exceptionnellement facilement en utilisant Groovy, et le code est très lisible.

Fondamentalement, la variable de texte sera écrite dans contacts.xml pour chaque ligne du contactData.csv, et le tableau fields contient chaque colonne.

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, 2016-04-10 20:04:49

Vous pouvez utiliser XSLT. Google il et vous trouverez quelques exemples par exemple CSV à XML Si vous utilisez XSLT, vous pouvez ensuite convertir le XML au format de votre choix.

 12
Author: Simmo, 2013-02-07 10:41:10

Il existe également une bonne bibliothèque ServingXML de Daniel Parker, qui est capable de convertir presque tous les formats de texte brut en XML et vice-versa.

L'exemple pour votre cas peut être trouvé ici: Il utilise l'en-tête du champ dans le fichier CSV comme nom d'élément XML.

 8
Author: Lukáš Rampa, 2013-02-07 10:45:43

Pour autant que je sache, il n'y a pas de bibliothèque prête à l'emploi pour le faire pour vous, mais la production d'un outil capable de traduire du CSV au XML ne devrait vous obliger qu'à écrire un analyseur CSV brut et à brancher JDOM (ou votre bibliothèque XML Java de choix) avec du code de colle.

 8
Author: Matt, 2016-04-10 20:56:11

Il n'y a rien que je sache qui puisse le faire sans que vous écriviez au moins un peu de code... Vous aurez besoin de 2 bibliothèques séparées:

  • Un cadre d'analyse CSV
  • Un cadre de Sérialisation XML

L'analyseur CSV que je recommanderais (sauf si vous voulez vous amuser un peu à écrire votre propre analyseur CSV) est OpenCSV (Un projet SourceForge pour analyser les données CSV)

Le framework de sérialisation XML devrait être quelque chose qui peut évoluer si vous le souhaitez transformer un grand (ou énorme) fichier CSV en XML: Ma recommandation est le Sun Java Streaming XML Parser Framework (Voir ici) qui permet l'extraction ET LA sérialisation.

 7
Author: Claude Houle, 2013-11-26 00:02:54

Cela peut être trop basique ou limité d'une solution, mais ne pourriez-vous pas faire un String.split() sur chaque ligne du fichier, mémoriser le tableau de résultats de la première ligne pour générer le XML, et simplement cracher les données du tableau de chaque ligne avec les éléments XML appropriés remplissant chaque itération d'une boucle?

 4
Author: saint_groceon, 2013-11-26 00:02:16

La famille de processeurs Jackson a des backends pour plusieurs formats de données, pas seulement JSON. Cela inclut à la fois XML ( https://github.com/FasterXML/jackson-dataformat-xml ) et CSV ( https://github.com/FasterXML/jackson-dataformat-csv / ) backends.

La conversion reposerait sur la lecture de l'entrée avec le backend CSV, l'écriture en utilisant le backend XML. C'est plus facile à faire si vous avez (ou pouvez définir) un POJO pour les entrées par ligne (CSV). Ce n'est pas une exigence stricte, car le contenu de CSV peut être lisez également "non typé" (une séquence de tableaux String), mais nécessite un peu plus de travail sur la sortie XML.

Pour le côté XML, vous auriez besoin d'un objet racine wrapper pour contenir un tableau ou List d'objets à sérialiser.

 4
Author: StaxMan, 2015-04-29 20:01:12

J'ai eu le même problème et j'avais besoin d'une application pour convertir un fichier CSV en fichier XML pour l'un de mes projets, mais je n'ai rien trouvé de gratuit et assez bon sur le net, j'ai donc codé ma propre application Java Swing CSVtoXML.

Il est disponible sur mon site web ICI. Espérons qu'il saura vous aider.

Sinon, vous pouvez facilement coder le vôtre comme je l'ai fait; Le code source est à l'intérieur du fichier jar, alors modifiez-le selon vos besoins s'il ne répond pas à vos besoins.

 3
Author: Ibrabel, 2014-08-18 11:14:48

Pour le CSV, vous pouvez utiliser ma petite bibliothèque open source

 3
Author: Arne Burmeister, 2018-03-20 19:07:38