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