CSV를 XML 파일로 변환하는 Java lib 또는 앱? [닫은]


114

데이터 파일을 파일 로 변환 할 수 있는 Java에 기존 애플리케이션 또는 라이브러리가 있습니까? CSVXML

XML태그 컬럼 헤딩을 포함 가능성이 첫 번째 행을 통해 제공 될 것이다.


47
이것이 자바의 태그에 대한 첫 번째 질문 인 것 같습니다.
Paul Vargas

8
@Paul 그뿐만 아니라 123입니다!
bjb568 2014


1
@ bjb568 오. 하하

4
SO의 Java에 대한 첫 번째 게시물이 주제를 벗어난 것으로 마감 된 것은 당연합니다
.

답변:


66

아마도 이것이 도움이 될 것입니다 : JSefa

이 도구로 CSV 파일을 읽고 XML로 직렬화 할 수 있습니다.


47

위의 다른 방법과 마찬가지로 한 단계 만 수행 할 수있는 방법은 없지만 매우 간단한 외부 라이브러리를 사용할 준비가 되었으면 다음을 제안합니다.

CSV 구문 분석을위한 OpenCsv (작고 간단하고 안정적이며 사용하기 쉬움)

XML을 구문 분석 / 직렬화하는 Xstream (매우 사용하기 쉽고 사람이 읽을 수있는 완전히 읽을 수있는 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>

27

나는 당신이 자바를 요청했다는 것을 알고 있지만 이것은 스크립팅 언어에 잘 맞는 작업이라고 생각합니다. 다음은 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을 stdout에 씁니다.

<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 라이브러리를 호출하여 구문 분석을 수행 한 다음 마크 업 빌더를 사용할 수 있습니다. 이것을 보여주기 위해 답변을 편집 할 수 있습니다.
Peter Kelley

18

일반적으로 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");

그리고 구문 분석 된 개체의 컬렉션이 있습니다.

도움이 되었기를 바랍니다.


+1은 특수 효과 사용입니다. 불행히도 오늘
Stephan

예, 그 이후로 개발을 계속할 시간이 없었지만 매우 안정적입니다.
콜리

17

이 솔루션에는 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>

15

가장 큰 차이점은 JSefa가 가져 오는 은 자바 객체를 CSV / XML / etc 파일로 직렬화 할 수 있고 자바 객체로 역 직렬화 할 수 있다는 것입니다. 그리고 그것은 출력에 대한 많은 제어를 제공하는 주석에 의해 구동됩니다.

JFileHelpers도 흥미로워 보입니다.


14

나는 당신이 이것을하려는 이유를 이해하지 못합니다. 마치화물 컬트 코딩처럼 들립니다.

CSV 파일을 XML로 변환해도 값이 추가되지 않습니다. 프로그램이 이미 CSV 파일을 읽고 있으므로 XML이 필요하다고 주장하는 것은 작동하지 않습니다.

반면에 CSV 파일을 읽고 값으로 무언가 를 수행 한 다음 XML로 직렬화하는 것은 의미가 있지만 (XML을 사용하는 것이 의미가있는 한 ...;)) 이미 다음과 같은 방법을 가지고있을 것입니다. XML로 직렬화.


14

Groovy를 사용하면 예외적으로 쉽게이 작업을 수행 할 수 있으며 코드는 매우 읽기 쉽습니다.

기본적으로 텍스트 변수는의 contacts.xml각 줄에 기록되며 contactData.csvfields 배열에는 각 열이 포함됩니다.

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>"""
}

7
CSV는 간단하지만 일반적으로 쉼표로 분할하면 충분할 정도로 간단하지 않습니다.
Alan Krueger

12

XSLT를 사용할 수 있습니다 . Google it과 몇 가지 예를 찾을 수 있습니다. 예를 들어 CSV에서 XML로 XSLT 를 사용 하면 원하는 형식으로 XML을 변환 할 수 있습니다.



7

최소한 약간의 코드를 작성하지 않고도이 작업을 수행 할 수 있다는 것을 아는 것은 없습니다. 2 개의 별도 라이브러리가 필요합니다.

  • CSV 파서 프레임 워크
  • XML 직렬화 프레임 워크

내가 추천하고 싶은 CSV 파서는 (CSV 파서를 작성하는 데 약간의 재미를 원하지 않는 한) OpenCSV (CSV 데이터 파싱을위한 SourceForge 프로젝트)입니다.

XML 직렬화 프레임 워크는 대용량 (또는 대용량) CSV 파일을 XML로 변환하려는 경우 확장 할 수있는 것이어야합니다. 필자 는 풀 구문 분석 및 직렬화를 허용 하는 Sun Java Streaming XML Parser Framework ( 여기 참조 )를 권장합니다 .


7

내가 아는 한이 작업을 수행 할 준비된 라이브러리는 없지만 CSV에서 XML로 번역 할 수있는 도구를 생성하려면 원유 CSV 파서를 작성하고 JDOM (또는 XML Java 라이브러리)을 연결하기 만하면됩니다. 선택) 일부 접착제 코드.


4

Jackson 프로세서 제품군에는 JSON뿐만 아니라 여러 데이터 형식에 대한 백엔드가 있습니다. 여기에는 XML ( https://github.com/FasterXML/jackson-dataformat-xml ) 및 CSV ( https://github.com/FasterXML/jackson-dataformat-csv/가 모두 포함됩니다. ) 백엔드 .

변환은 CSV 백엔드로 입력을 읽고 XML 백엔드를 사용하여 작성합니다. 이것은 행별 (CSV) 항목에 대한 POJO가 있거나 정의 할 수있는 경우 수행하는 가장 쉬운 방법입니다. CSV의 콘텐츠도 "유형이 지정되지 않은"것으로 읽힐 수 있으므로 엄격한 요구 사항은 아닙니다.String 배열 ) XML 출력에 대해 약간의 작업이 필요합니다.

XML 측의 경우 List직렬화 할 배열 또는 개체를 포함하는 래퍼 루트 개체가 필요합니다 .


3

나는 같은 문제가 있었고 내 프로젝트 중 하나를 위해 CSV 파일을 XML 파일로 변환하는 응용 프로그램이 필요했지만 인터넷에서 무료로 좋은 것을 찾지 못했기 때문에 Java Swing CSVtoXML 응용 프로그램을 코딩했습니다.

여기 내 웹 사이트에서 사용할 수 있습니다. . 도움이되기를 바랍니다.

그렇지 않다면 나처럼 쉽게 코딩 할 수 있습니다. 소스 코드는 jar 파일 안에 있으므로 요구 사항을 충족하지 않으면 필요에 따라 수정하십시오.



3

이것은 너무 기본적이거나 솔루션이 제한적일 수 있지만 String.split()파일의 각 줄에서 XML을 생성하기 위해 첫 번째 줄의 결과 배열을 기억하고 적절한 XML로 각 줄의 배열 데이터를 뱉어 낼 수는 없습니다. 루프의 각 반복을 채우는 요소?


2
CSV 파일에 데이터에 따옴표가 붙은 쉼표가 포함되어 있지 않은 경우는 매우 일반적입니다.
Alan Krueger
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.