Java Lib или приложение для преобразования CSV в файл XML?

голоса
95

Есть ли существующие приложения или библиотеки в Java , которая позволит мне преобразовать CSVфайл данных в XMLфайл?

Эти XMLметки будут предоставлены через , возможно , в первой строке , содержащей заголовки столбцов.

Задан 01/08/2008 в 17:08
источник пользователем
На других языках...                            


16 ответов

голоса
60

Может быть , это может помочь: JSefa

Вы можете читать CSV-файл с помощью этого инструмента и сериализовать его в XML.

Ответил 01/08/2008 в 19:51
источник пользователем

голоса
45

Как показывают приведенные выше других, я не знаю ни одного шага, как сделать это, но если вы готовы использовать очень простые внешние библиотеки, я хотел бы предложить:

OpenCsv для разбора CSV (маленький, простой, надежный и простой в использовании)

XSTREAM для разбора / сериализации XML (очень и очень проста в использовании, а также создание читаемый XML полностью человеческое)

Используя те же выборочные данные, как указано выше, код будет выглядеть следующим образом:

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

Производство следующего результата: (Xstream позволяет очень тонкую настройку результата ...)

<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>
Ответил 10/09/2008 в 08:06
источник пользователем

голоса
24

Я знаю, что вы просили Java, но это поражает меня как задача хорошо подходит для языка сценариев. Вот быстрый (очень простой) решение написано в 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])
            }
        }
    }
}

Пишет следующий XML в стандартный вывод:

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

Тем не менее, делает код очень простой синтаксический (не принимая во внимание цитироваться или сбежавшего запятые), и он не учитывает возможных отсутствующих данных.

Ответил 09/08/2008 в 12:06
источник пользователем

голоса
17

У меня есть рамки с открытым исходным кодом для работы с CSV и плоскими файлами в целом. Может быть , это стоит посмотреть: JFileHelpers .

С этим инструментарием вы можете написать код, используя фасоль, как:

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

а затем просто разобрать текстовые файлы с помощью:

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

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

И вы будете иметь набор проанализированных объектов.

Надеюсь, это поможет!

Ответил 28/09/2008 в 00:43
источник пользователем

голоса
15

Это решение не нуждается в CSV или XML-библиотеки, и я знаю, он не обрабатывает любые недопустимые символы и вопросы кодирования, но вы можете быть заинтересованы в нем, а также, при условии, ваш вклад CSV не нарушает указанные выше правила.

Внимание: Вы не должны использовать этот код , если вы не знаете , что вы делаете или не иметь возможности использовать дополнительную библиотеку (возможно в некоторых бюрократических проектах) ... Использование StringBuffer для более старых сред выполнения ...

Так что здесь мы идем:

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

Входная 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

Полученный выход:

<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>
Ответил 22/08/2008 в 00:17
источник пользователем

голоса
14

Большая разница в том , что JSefa приносит в том , что он может сериализовать ваши объекты Java в CSV / XML / и т.д. файлы и может десериализацию обратно к объектам Java. И это обусловлено аннотациями , который дает вам много контроля над выводом.

JFileHelpers также выглядит интересно.

Ответил 11/08/2010 в 06:49
источник пользователем

голоса
14

Вы можете сделать это исключительно легко с помощью Groovy, и коды очень читаемые.

В основном, переменная текст будет записан в contacts.xmlкаждой строке в contactData.csv, а массив полей содержит каждый столбец.

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>"""
}
Ответил 02/10/2008 в 07:08
источник пользователем

голоса
13

Я не понимаю, почему вы хотели бы сделать это. Это звучит почти как культ карго кодирования.

Преобразование файла CSV в XML не добавляет никакой ценности. Ваша программа уже читает файл CSV, так рассуждая, что вам нужно XML не работает.

С другой стороны, чтение файла CSV, делать что - то со значениями, а затем сериализации XML имеет смысл (ну, так же , как с помощью XML может иметь смысл ...;)) , но вы , мол , уже есть средства сериализации XML.

Ответил 01/08/2008 в 20:21
источник пользователем

голоса
11

Вы можете использовать XSLT . Google, и вы найдете несколько примеров , например , CSV в XML Если вы используете XSLT , то вы можете преобразовать XML в любом формате вы хотите.

Ответил 16/10/2008 в 15:33
источник пользователем

голоса
8

Существует также хорошая библиотека ServingXML Даниэль Паркер, который способен конвертировать практически любой формат обычного текста в XML и обратно.

Пример для случая можно найти здесь : Он использует заголовок поля в CSV - файл в качестве имени XML - элемента.

Ответил 30/09/2008 в 22:22
источник пользователем

голоса
7

Там нет ничего, что я не знаю, что может сделать это без вас, по крайней мере писать немного коды ... Вам понадобятся 2 отдельной библиотека:

  • Рамочный CSV Parser
  • XML сериализации Framework

CSV парсер я рекомендовал бы (если вы не хотите иметь немного удовольствия, чтобы написать свой собственный CSV Parser) является OpenCSV (A SourceForge Project для разбора CSV данных)

Сериализация Framework XML должен быть чем - то , что может масштабироваться в случае , если вы хотите превратить большой (или огромный) файл CSV в XML: Моя рекомендация является Sun Java Streaming Parser Framework XML (см здесь ) , который позволяет вытягивать-синтаксический анализ и сериализацию.

Ответил 04/08/2008 в 02:07
источник пользователем

голоса
7

Насколько я знаю, нет готовых библиотек, чтобы сделать это для вас, но производит инструмент, способный переводить из CSV в XML необходимо только, чтобы вы написали сырую CSV парсер и подключить JDOM (или ваш XML Java библиотеку выбор) с некоторым связующим кодом.

Ответил 02/08/2008 в 20:06
источник пользователем

голоса
4

Джексон семейство процессоров имеют движки для нескольких форматов данных, а не только JSON. Это включает в себя как XML ( https://github.com/FasterXML/jackson-dataformat-xml ) и CSV ( https://github.com/FasterXML/jackson-dataformat-csv/ ) движками.

Конверсия будет опираться на чтение входных данных с CSV бэкэндом, написать с помощью XML - бэкенд. Легче всего это сделать , если у вас есть (или может определить) POJO для на-ряду (CSV) записей. Это не является строгим требованием, поскольку содержимое из CSV может быть прочитано «нетипизированное» , а также (последовательность Stringмассивов), но требует немного больше работы на выходе XML.

Для стороны XML, вам потребуется обертка корневого объект содержит массив или Listобъекты для сериализации.

Ответил 29/04/2015 в 20:01
источник пользователем

голоса
3

У меня была такая же проблема и требуется приложение для преобразования файла CSV в файл XML для одного из моих проектов, но не нашел ничего свободного и достаточно хорошо в сети, так что я закодированы мое собственное приложение Свинг CSVtoXML Java.

Он доступен с моего сайта ЗДЕСЬ . Надеюсь , что это поможет.

Если нет, то вы можете легко закодировать свой собственный, как я сделал; Исходный код находится внутри файла .jar так изменить его, как вам нужно, если она не заполнит ваше требование.

Ответил 16/04/2014 в 01:12
источник пользователем

голоса
3

Для CSV части, вы можете использовать мою маленькую библиотеку с открытым исходным кодом

Ответил 16/09/2008 в 17:07
источник пользователем

голоса
3

Это может быть слишком основным или ограничен из раствора, но не могли бы вы сделать String.split()на каждую строке файла, запоминания результата массива первой строки для создания XML, и просто плюет массив данных на каждую линию с надлежащим XML элементы дополняя каждую итерацию цикла?

Ответил 01/08/2008 в 17:31
источник пользователем

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