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


есть ли существующее приложение или библиотека в Java что позволит мне преобразовать данные ?

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

16 99

16 ответов:

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

вы можете прочитать 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.

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

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

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

Это решение не нуждается в каких-либо библиотеках 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());

входной тест.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>

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

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

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

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

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

вы можете сделать это чрезвычайно легко с помощью 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. Google it, и вы найдете несколько примеров, например CSV в XML Если вы используете XSLT затем вы можете конвертировать XML в любой формат, который вы хотите.

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

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

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

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

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

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

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

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

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

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

для XML-стороны вам понадобится корневой объект оболочки, содержащий массив или List объектов для сериализации.

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

это доступно с моего сайта здесь. Надеюсь, что это поможет вам.

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

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