Java lib или приложение для конвертации CSV в файл XML? [закрыто]

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

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

1.08.2008 16:08:52
Кажется, это первый вопрос с тегом Java в SO.
Paul Vargas 12.09.2013 21:24:53
@ Пол Не только это, это также 123!
bjb568 22.02.2014 06:35:03
bjb568 9.07.2017 23:37:44
@ bjb568 Ох. ха-ха
user7627726 10.07.2017 03:19:47
Неудивительно, что первый в истории пост для java в SO был закрыт как не по теме: D
Sir. Hedgehog 8.03.2019 15:46:29
16 ОТВЕТОВ
РЕШЕНИЕ

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

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

65
7.02.2013 10:36:04

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

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>
46
27.01.2016 06:06:59

Я знаю, что вы спрашивали о 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>

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

26
7.02.2013 10:37:12
Таким образом, вы можете вызвать библиотеку CSV для анализа и затем использовать конструктор разметки. Может быть, вы могли бы отредактировать свой ответ, чтобы показать это.
Peter Kelley 30.09.2008 22:55:40

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

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

@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");

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

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

18
7.02.2013 18:56:09
+1 за использование аннотаций. К сожалению, на сегодняшний день кажется, что у проекта нет новой версии с 2009-08-11 ...
Stephan 12.11.2012 15:47:45
Да, у меня не было времени продолжать разработку с тех пор, но она очень стабильна.
kolrie 12.11.2012 18:29:28

Это решение не требует каких-либо библиотек 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>
17
2.11.2015 14:14:39

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

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

15
7.02.2013 10:40:32

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

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

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

14
1.08.2008 19:21:57

Вы можете сделать это исключительно легко, используя Groovy, и код очень удобочитаемый.

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

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>"""
}
14
10.04.2016 20:04:49
CSV прост, но, как правило, никогда не бывает достаточно простым, чтобы разделить запятую.
Alan Krueger 7.07.2010 16:18:23

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

12
7.02.2013 10:41:10

Также есть хорошая библиотека ServingXML от Daniel Parker, которая способна конвертировать практически любой простой текстовый формат в XML и обратно.

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

8
7.02.2013 10:45:43

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

  • CSV Parser Framework
  • Структура XML-сериализации

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

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

7
26.11.2013 00:02:54

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

7
10.04.2016 20:56:11

Семейство процессоров Jackson имеет бэкенды для нескольких форматов данных, а не только 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объектов для сериализации.

4
29.04.2015 20:01:12

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

3
26.11.2013 00:02:16
Нет, если ваш CSV-файл содержит кавычки в данных, что довольно часто.
Alan Krueger 7.07.2010 16:19:43

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

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

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

3
18.08.2014 11:14:48

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

3
20.03.2018 19:07:38