Question

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

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

Était-ce utile?

La solution

Peut-être que ceci pourrait aider : JSefa

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

Autres conseils

Comme les autres ci-dessus, je ne connais pas de moyen en une seule étape de procéder, mais si vous êtes prêt à utiliser des bibliothèques externes très simples, je suggère :

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

Xstream pour analyser/sérialiser XML (très très facile à utiliser et créer du 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();
        }
    }
}

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

Je sais que vous avez demandé Java, mais cela me semble être 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 code XML suivant sur la sortie standard :

<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 prenant pas en compte les virgules entre guillemets ou échappées) et ne tient pas compte des éventuelles données absentes.

J'ai un framework open source pour travailler avec des fichiers CSV et plats en général.Cela vaut peut-être la peine de regarder : JFileHelpers.

Avec cette boîte à outils, vous pouvez écrire du code à l'aide de 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 cela pourra aider!

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

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

Alors c'est parti :

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'entrée test.csv (volée dans 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 obtenu :

<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 différence est que JSefa Ce qu'apporte, c'est qu'il peut sérialiser vos objets Java en fichiers CSV/XML/etc et peut les désérialiser en objets Java.Et il est piloté par des annotations qui vous donnent beaucoup de contrôle sur la sortie.

JFileHelpers semble également intéressant.

Je ne comprends pas pourquoi vous voudriez faire ça.Cela ressemble presque à du codage de culte du cargo.

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

Par contre, en lisant le fichier CSV, en faisant quelque chose avec les valeurs, puis la sérialisation en XML a du sens (enfin, autant que l'utilisation de XML peut avoir du sens...;)) mais vous auriez déjà un moyen de sérialiser en XML.

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

Fondamentalement, la variable texte sera écrite dans contacts.xml pour chaque ligne du contactData.csv, et le tableau des champs 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>"""
}

Vous pourriez utiliser XSLT.Recherchez-le sur Google et vous trouverez quelques exemples, par ex. CSV vers XMLSi tu utilises XSLT vous pouvez ensuite convertir le XML dans le format de votre choix.

Il y a aussi une bonne bibliothèque ServiceXML par Daniel Parker, qui est capable de convertir presque tous les formats de texte brut en XML et inversement.

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

À ma connaissance, rien ne peut faire cela sans que vous écriviez au moins un peu de code...Vous aurez besoin de 2 bibliothèques distinctes :

  • Un cadre d'analyseur CSV
  • Un cadre de sérialisation XML

L'analyseur CSV que je recommanderais (sauf si vous voulez vous amuser un peu en écrivant 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 évoluer au cas où vous souhaiteriez transformer un fichier CSV volumineux (ou énorme) en XML :Ma recommandation est le Sun Java Streaming XML Parser Framework (voir ici) qui permet l'analyse pull-parsing ET la sérialisation.

Autant que je sache, il n'existe pas de bibliothèque prête à l'emploi pour faire cela pour vous, mais produire un outil capable de traduire de CSV en XML ne devrait vous obliger qu'à écrire un analyseur CSV brut et à connecter JDOM (ou votre bibliothèque XML Java de choix) avec du code de colle.

La famille de processeurs Jackson dispose de 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/) back-ends.

La conversion reposerait sur la lecture des entrées avec le backend CSV, l'écriture à l'aide du backend XML.C'est plus simple à faire si vous disposez (ou pouvez définir) un POJO pour les entrées par ligne (CSV).Il ne s'agit pas d'une exigence stricte, car le contenu d'un CSV peut également être lu « non typé » (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.

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

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 d'assez performant sur le net, j'ai donc codé ma propre application Java Swing CSVtoXML.

Il est disponible sur mon site ICI.J'espère que cela vous aidera.

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

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

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top