Java'da bir CSV
veri dosyasını dosyaya dönüştürmeme izin verecek mevcut bir uygulama veya kitaplık var mı XML
?
XML
Etiketler sütun başlıkları içeren muhtemelen ilk satırı boyunca sağlanmış olacaktır.
Java'da bir CSV
veri dosyasını dosyaya dönüştürmeme izin verecek mevcut bir uygulama veya kitaplık var mı XML
?
XML
Etiketler sütun başlıkları içeren muhtemelen ilk satırı boyunca sağlanmış olacaktır.
Yanıtlar:
Yukarıdaki diğerleri gibi, bunu yapmanın tek adımlı bir yolunu bilmiyorum, ancak çok basit harici kitaplıkları kullanmaya hazırsanız, şunları öneririm:
CSV'yi ayrıştırmak için OpenCsv (küçük, basit, güvenilir ve kullanımı kolay)
XML'i ayrıştırmak / serileştirmek için Xstream (kullanımı çok kolay ve tamamen insan tarafından okunabilir xml oluşturma)
Yukarıdakiyle aynı örnek verileri kullanarak, kod şöyle görünür:
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();
}
}
}
Aşağıdaki sonucun oluşturulması: (Xstream, sonucun çok ince ayarlanmasına izin verir ...)
<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 istediğini biliyorum, ama bu beni bir betik diline çok uygun bir görev olarak etkiliyor. İşte Groovy'de yazılmış hızlı (çok basit) bir çözüm.
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])
}
}
}
}
Aşağıdaki XML'yi standart çıktıya yazar:
<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>
Bununla birlikte, kod çok basit bir çözümleme yapar (alıntılanan veya kaçan virgülleri hesaba katmadan) ve olası eksik verileri hesaba katmaz.
Genel olarak CSV ve düz dosyalarla çalışmak için açık kaynaklı bir çerçevem var. Belki bakmaya değer: JFileHelpers .
Bu araç takımı ile fasulye kullanarak kod yazabilirsiniz, örneğin:
@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;
}
ve ardından metin dosyalarınızı şu şekilde ayrıştırın:
FileHelperEngine<Customer> engine =
new FileHelperEngine<Customer>(Customer.class);
List<Customer> customers =
new ArrayList<Customer>();
customers = engine.readResource(
"/samples/customers-fixed.txt");
Ve ayrıştırılmış nesnelerden oluşan bir koleksiyonunuz olacak.
Umarım yardımcı olur!
Bu çözüm herhangi bir CSV veya XML kitaplığına ihtiyaç duymaz ve biliyorum, yasadışı karakterleri ve kodlama sorunlarını ele almaz, ancak CSV girişinizin yukarıda belirtilen kuralları ihlal etmemesi koşuluyla, bununla da ilgilenebilirsiniz.
Dikkat: Ne yaptığınızı bilmiyorsanız veya başka bir kitaplık kullanma şansınız olmadıkça bu kodu kullanmamalısınız (bazı bürokratik projelerde mümkündür) ... Eski Çalışma Zamanı Ortamları için bir StringBuffer kullanın ...
İşte başlıyoruz:
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());
Giriş test.csv (bu sayfadaki başka bir cevaptan çalındı):
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
Ortaya çıkan çıktı:
<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>
JSefa'nın getirdiği en büyük fark, java nesnelerinizi CSV / XML / etc dosyalarına serileştirebilmesi ve java nesnelerine yeniden serileştirebilmesidir. Ve çıktı üzerinde size çok fazla kontrol sağlayan ek açıklamalarla yönlendirilir.
JFileHelpers da ilginç görünüyor.
Bunu neden yapmak isteyeceğini anlamıyorum. Neredeyse kargo kült kodlamasına benziyor.
Bir CSV dosyasını XML'e dönüştürmek herhangi bir değer katmaz. Programınız zaten CSV dosyasını okuyor, bu nedenle XML'e ihtiyacınız olduğunu savunmak işe yaramıyor.
Öte yandan, CSV dosyasını okumak, değerlerle bir şeyler yapmak ve ardından XML'e serileştirmek mantıklıdır (XML kullanmanın mantıklı olabileceği kadar ...;) ama sözüm ona zaten XML'e serileştirme.
Bunu Groovy kullanarak son derece kolay bir şekilde yapabilirsiniz ve kod çok okunabilir.
Temel olarak, metin değişkeni contacts.xml
içindeki her satır için yazılır contactData.csv
ve alanlar dizisi her sütunu içerir.
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 kullanabilirsiniz . Google it ve birkaç örnek bulacaksınız, örneğin CSV'den XML'e XSLT kullanıyorsanız , XML'i istediğiniz biçime dönüştürebilirsiniz.
Hemen hemen her düz metin biçimini XML'e ve geri dönüştürebilen Daniel Parker'ın sunduğu ServingXML adlı iyi bir kitaplık da vardır .
Durumunuza ilişkin örnek burada bulunabilir : XML öğe adı olarak CSV dosyasındaki alan başlığını kullanır.
En azından biraz kod yazmadan bunu yapabileceğini bildiğim hiçbir şey yok ... 2 ayrı kitaplığa ihtiyacınız olacak:
Tavsiye edeceğim CSV ayrıştırıcısı (kendi CSV Ayrıştırıcınızı yazmak için biraz eğlenmek istemiyorsanız) OpenCSV'dir (CSV Verilerini ayrıştırmak için bir SourceForge Projesi)
XML Serileştirme Çerçevesi, büyük (veya çok büyük) CSV dosyasını XML'e dönüştürmek istemeniz durumunda ölçeklenebilecek bir şey olmalıdır: Benim önerim , çek-ayrıştırmaya VE serileştirmeye izin veren Sun Java Akışı XML Ayrıştırıcı Çerçevesidir ( buraya bakın ).
Jackson işlemci ailesi, yalnızca JSON için değil, birden çok veri formatı için arka uçlara sahiptir. Buna hem XML ( https://github.com/FasterXML/jackson-dataformat-xml ) hem de CSV ( https://github.com/FasterXML/jackson-dataformat-csv/) dahildir. ) arka uçları dahildir.
Dönüşüm, girişin CSV arka uç ile okunmasına dayanır, XML arka uç kullanarak yazılır. Satır başına (CSV) girişler için bir POJO'ya sahipseniz (veya tanımlayabiliyorsanız) bunu yapmak en kolay yoldur. CSV içeriği "türlenmemiş" olarak da okunabileceğinden bu katı bir gereklilik değildir (bir diziString
dizi) , ancak XML çıktısı üzerinde biraz daha fazla çalışma gerektirir.
XML tarafı için, diziyi veya List
serileştirilecek nesneleri içeren bir sarmalayıcı kök nesnesine ihtiyacınız olacaktır .
Aynı sorunu yaşadım ve projelerimden biri için bir CSV dosyasını XML dosyasına dönüştürmek için bir uygulamaya ihtiyacım vardı, ancak internette özgür ve yeterince iyi bir şey bulamadım, bu yüzden kendi Java Swing CSVtoXML uygulamamı kodladım.
BURAYA web sitemden edinilebilir . Umarım size yardımcı olur.
Değilse, benim yaptığım gibi kendi kodunuzu kolayca kodlayabilirsiniz; Kaynak kodu jar dosyasının içindedir, bu nedenle gereksinimlerinizi karşılamıyorsa ihtiyacınız olduğu gibi değiştirin.
CSV Bölümü için benim küçük açık kaynak kitaplığımı kullanabilirsiniz
Bu, bir çözüm için çok basit veya sınırlı olabilir, ancak String.split()
dosyanın her satırında, XML'yi oluşturmak için ilk satırın sonuç dizisini hatırlayarak ve her satırın dizi verilerini uygun XML ile tüküremezsiniz. bir döngünün her yinelemesini dolduran öğeler?