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

StackOverflow https://stackoverflow.com/questions/123

  •  08-06-2019
  •  | 
  •  

Вопрос

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

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

Это было полезно?

Решение

Возможно, это может помочь: ДжСефа

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

Другие советы

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

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>

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

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

У меня есть платформа с открытым исходным кодом для работы с 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");

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

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

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

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

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

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

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

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

Вы можете сделать это исключительно легко, используя 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>"""
}

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

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

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

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

  • Платформа синтаксического анализа CSV
  • Платформа сериализации XML

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

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

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

Семейство процессоров 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 объектов для сериализации.

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top