Java lib ou application pour convertir CSV en fichier XML?

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

les étiquettes XML pourraient être fournies par l'intermédiaire de la première rangée contenant les titres des colonnes.

99
demandé sur Mohit 2008-08-01 20:08:52

16 réponses

peut-être que cela pourrait aider: JSefa

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

62
répondu svrist 2013-02-07 10:36:04

comme les autres ci-dessus, je ne connais pas de méthode en une étape, mais si vous êtes prêt à utiliser des bibliothèques externes très simples, je suggérerais:

OpenCsv pour l'analyse CSV (petit, simple, fiable et facile à utiliser)

Xstream pour analyser / sérialiser XML (très très facile à utiliser, et la création de xml entièrement lisible par l'humain)

en utilisant les mêmes données d'échantillon que ci-dessus, le code serait ressemble à:

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 un réglage très fin 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
répondu 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 dans Groovy.

.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 à 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 fait très simple parsing (ne pas prendre en compte compte guillemets cités ou échappés) et il ne tient pas compte des possibles données absentes.

25
répondu Anthony Cramp 2013-02-07 10:37:12

j'ai un cadre opensource pour travailler avec CSV et les fichiers plats en général. Peut-être que ça vaut le coup de regarder: JFileHelpers .

avec cette boîte à outils, vous pouvez écrire du code en utilisant des haricots, 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;  
}

et 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 déchiffrés.

Espère que ça aide!

18
répondu kolrie 2013-02-07 18:56:09

Cette solution n'a pas besoin de bibliothèques CSV ou XML et, je sais, elle ne traite pas les caractères illégaux et les problèmes d'encodage, mais vous pourriez être intéressé par elle aussi, à condition que votre entrée CSV ne viole pas les règles mentionnées ci-dessus.

Attention: vous ne devez pas utiliser ce code à moins de savoir ce que vous faites ou de ne pas avoir la chance d'utiliser une autre bibliothèque (possible dans certains projets bureaucratiques)... Utiliser un StringBuffer pour les plus âgés Environnements D'Exécution...

allons-y Alors:

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

Le résultat:

<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
répondu Martin Klinke 2015-11-02 14:14:39

je ne comprends pas pourquoi vous voulez le faire. Ça ressemble presque à un code culte de la cargaison.

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

d'un autre côté, lire le fichier CSV, faire quelque chose avec les valeurs, puis sérialiser au XML fait du sens (Eh bien, autant qu'utiliser XML peut faire du sens... ;)) mais vous auriez soi-disant déjà un moyen de sérialiser au XML.

15
répondu 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 aux fichiers CSV/XML/etc et peut deserialiser retour aux 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
répondu 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 textuelle sera écrite à contacts.xml pour chaque ligne dans le 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
répondu abarax 2016-04-10 20:04:49

vous pouvez utiliser XSLT . Google it et vous trouverez quelques exemples par exemple CSV à XML Si vous utilisez XSLT vous pouvez alors convertir le XML à n'importe quel format que vous voulez.

12
répondu Simmo 2013-02-07 10:41:10

il y a aussi une bonne bibliothèque ServingXML de Daniel Parker, qui est capable de convertir presque n'importe quel format de texte simple en XML et retour.

l'exemple pour votre cas peut être trouvé ici : il utilise le titre du champ dans le fichier CSV comme le nom de l'élément XML.

8
répondu Lukáš Rampa 2013-02-07 10:45:43

autant que je sache, il n'y a pas de bibliothèque toute faite pour le faire pour vous, mais produire un outil capable de traduire de CSV en XML ne devrait vous obliger qu'à écrire un parser CSV brut et à raccorder JDOM (ou votre bibliothèque Java XML de choix) avec un peu de code de colle.

8
répondu Matt 2016-04-10 20:56:11

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

  • CSV Analyseur Cadre
  • Une Sérialisation XML Cadre

L'analyseur CSV que je recommande (à moins que vous ne vouliez avoir un peu de plaisir à écrire votre propre analyseur CSV) est OpenCSV (un projet SourceForge pour l'analyse des données CSV)

Le cadre de sérialisation XML devrait être quelque chose qui peut être mis à l'échelle dans le cas où vous voulez transformer grand (ou énorme) fichier CSV en XML: ma recommandation est le Sun Java Streaming XML Parser Framework (voir ici ) qui permet l'analyse pull-et la sérialisation.

7
répondu 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, en se rappelant le tableau de résultat de la première ligne pour générer le XML, et recracher simplement les données du tableau de chaque ligne avec les éléments XML appropriés rembourrant chaque itération d'une boucle?

4
répondu saint_groceon 2013-11-26 00:02:16

la famille de processeurs Jackson a des sauvegardes pour les formats de données multiples, pas seulement JSON. Ceci inclut les deux XML ( https://github.com/FasterXML/jackson-dataformat-xml ) et CSV ( ) https://github.com/FasterXML/jackson-dataformat-csv / ) backends.

La Conversion

serait basée sur la lecture de l'entrée avec CSV backend, écrire en utilisant XML backend. Ceci est plus facile à faire si vous avez (ou pouvez définir) un POJO pour les entrées par ligne (CSV). C'est pas une exigence stricte, car le contenu de CSV peut être lu "untyped" aussi bien (une séquence de String tableaux), 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
répondu StaxMan 2015-04-29 20:01:12

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

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

si non, vous pouvez facilement coder votre propre comme je l'ai fait; le code source est à l'intérieur du fichier jar alors modifiez-le comme vous avez besoin si il ne pas remplir votre exigence.

3
répondu Ibrabel 2014-08-18 11:14:48

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

3
répondu Arne Burmeister 2018-03-20 19:07:38