Java lib ou une application pour convertir CSV dans un fichier XML?

voix
95

Y at - il une application existante ou d'une bibliothèque en Java qui me permettra de convertir un CSVfichier de données à un XMLfichier?

Les XMLétiquettes seraient fournies par le biais éventuellement la première rangée contenant têtes de colonne.

Créé 01/08/2008 à 17:08
source utilisateur
Dans d'autres langues...                            


16 réponses

voix
60

Peut - être que cela pourrait aider: JSefa

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

Créé 01/08/2008 à 19:51
source utilisateur

voix
45

Comme les autres ci-dessus, je ne sais pas comment une seule étape à faire, mais si vous êtes prêt à utiliser des bibliothèques externes très simples, je dirais:

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

Xstream pour analyser / sérialisation XML (très très facile à utiliser, et la création de XML lisible pleinement humain)

En utilisant les mêmes données d'échantillons comme ci-dessus, le code ressemblerait à ceci:

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>
Créé 10/09/2008 à 08:06
source utilisateur

voix
24

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) écrit 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])
            }
        }
    }
}

Rédige le code XML suivant 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 ne analyse très simple (sans tenir compte des virgules entre guillemets ou échappé) et il ne tient pas compte des éventuelles données absentes.

Créé 09/08/2008 à 12:06
source utilisateur

voix
17

J'ai un cadre opensource pour travailler avec CSV et fichiers plats en général. Peut-être qu'il vaut la peine 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;  
}

puis analyser 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!

Créé 28/09/2008 à 00:43
source utilisateur

voix
15

Cette solution n'a pas besoin de bibliothèques CSV ou XML et, je sais, il ne traite pas de caractères illégaux et les problèmes de codage, mais vous pourriez être intéressé par aussi bien, à condition que votre entrée CSV ne casse 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 ne pas la possibilité d'utiliser une autre bibliothèque (possible dans certains projets bureaucratiques) ... Utilisez un StringBuffer pour les anciens environnements d' exécution ...

nous allons alors voici:

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.csv d'entrée (volée à 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>
Créé 22/08/2008 à 00:17
source utilisateur

voix
14

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

JFileHelpers semble aussi intéressant.

Créé 11/08/2010 à 06:49
source utilisateur

voix
14

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

Fondamentalement, la variable texte sera écrit contacts.xmlpour chaque ligne dans le contactData.csv, et le tableau de 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>"""
}
Créé 02/10/2008 à 07:08
source utilisateur

voix
13

Je ne comprends pas pourquoi vous voulez faire. Il ressemble presque à un codage culte de la cargaison.

Conversion d'un fichier CSV à XML n'ajoute aucune valeur. Votre programme est en train de lire le fichier CSV déjà, en faisant valoir que si vous avez besoin XML ne fonctionne pas.

D'autre part, la lecture du fichier CSV, faire quelque chose avec les valeurs et sérialisation alors XML est logique (bien, autant que l' utilisation de XML peut donner un sens ...;)) , mais vous auriez soi - disant déjà un moyen de sérialisation XML.

Créé 01/08/2008 à 20:21
source utilisateur

voix
11

Vous pouvez utiliser XSLT . Google et vous trouverez quelques exemples , par exemple CSV XML Si vous utilisez XSLT vous pouvez convertir le XML en format que vous voulez.

Créé 16/10/2008 à 15:33
source utilisateur

voix
8

Il y a aussi une bonne bibliothèque ServingXML par Daniel Parker, qui est capable de convertir presque tous les formats de texte brut au format XML et le dos.

Vous trouverez l'exemple pour votre cas ici : Il utilise tête de champ dans le fichier CSV comme le nom de l' élément XML.

Créé 30/09/2008 à 22:22
source utilisateur

voix
7

Il n'y a rien que je connaisse qui peut le faire sans vous écrire au moins un peu de code ... Vous aurez besoin de 2 bibliothèque séparée:

  • Un cadre CSV Parser
  • Un cadre XML sérialisation

L'analyseur CSV Je recommande (sauf si vous voulez avoir un peu de plaisir à écrire votre propre CSV Parser) est OpenCSV (Un projet SourceForge pour l'analyse des données CSV)

Le cadre XML sérialisation devrait être quelque chose qui peut évoluer au cas où vous voulez transformer un grand (ou grand) fichier CSV XML: Ma recommandation est le cadre XML Sun Java en streaming Parser (voir ici ) qui permet l' analyse d' extraction et de sérialisation.

Créé 04/08/2008 à 02:07
source utilisateur

voix
7

Pour autant que je sache, il n'y a pas de bibliothèque ready-made à faire pour vous, mais la production d'un outil capable de traduire du CSV en XML ne devez vous avez besoin d'écrire un analyseur CSV brut et brancher JDOM (ou votre bibliothèque XML Java choix) avec un code de colle.

Créé 02/08/2008 à 20:06
source utilisateur

voix
4

Famille de processeurs Jackson a pour backends plusieurs formats de données, non seulement JSON. Cela inclut les documents XML ( https://github.com/FasterXML/jackson-dataformat-xml ) et CSV ( https://github.com/FasterXML/jackson-dataformat-csv/ ) backends.

La conversion se fierait à la lecture d' entrée avec back - end CSV, écrire en utilisant backend XML. Ceci 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, que le contenu du CSV peut être lu « typées » ainsi (une séquence de Stringtableaux), mais nécessite peu plus de travail sur la sortie XML.

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

Créé 29/04/2015 à 20:01
source utilisateur

voix
3

J'ai eu le même problème et avait besoin d'une application pour convertir un fichier CSV dans un fichier XML pour un de mes projets, mais n'a pas trouvé quoi que ce soit gratuit et assez bon sur le net, donc je codé ma propre application Java Swing CSVtoXML.

Il est disponible sur mon site ICI . Espérons que cela vous aidera.

Sinon, vous pouvez coder facilement votre propre comme je l'ai fait; Le code source est à l'intérieur du fichier jar afin de le modifier comme vous avez besoin si elle ne remplit pas votre exigence.

Créé 16/04/2014 à 01:12
source utilisateur

voix
3

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

Créé 16/09/2008 à 17:07
source utilisateur

voix
3

Cela peut être trop basique ou limitée d'une solution, mais ne pouvait pas vous faire String.split()sur chaque ligne du fichier, se souvenant du tableau de résultat de la première ligne pour générer le XML, et juste cracher les données du tableau de chaque ligne avec le XML approprié éléments rembourrage chaque itération d'une boucle?

Créé 01/08/2008 à 17:31
source utilisateur

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more