Java lib или приложение для конвертации CSV в XML файл?
есть ли существующее приложение или библиотека в Java что позволит мне преобразовать данные ?
The XML
теги будут предоставляться через, возможно, первую строку, содержащую заголовки столбцов.
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 части, вы можете использовать моя маленькая библиотека с открытым исходным кодом