2012-09-01 3 views
1

CSV 형식의 데이터를 XML로 변환하는 도구를 작성하고 있습니다. 사용자가 구문 분석 방법을 지정하면 출력용 XSD, CSV의 어느 필드가 결과 XML의 필드로 이동 하는지를 지정합니다.Java : 사용자 정의 XSD에 따라 XML을 작성하십시오.

는 는

(매우 간단한 사용 예) 예 :

CSV는

Ciccio;Pippo;Pappo 
1;2;3 

XSD

(more stuff...) 
<xs:element name="onetwo"> 
<xs:element name="three"> 
<xs:element name="four"> 

USER 내가 C#에서 이것을 구현했습니다

Ciccio -> onetwo 
    Pippo -> three 
    Pappo -> four 

규칙을 부여 데이터 세트를 사용하는 방법 나는 자바로 그것을합니까? DOM, JAXB 등이 있지만 XSD는 다른 방법으로 XML을 검증하는 용도로만 사용됩니다. 내가 잘못?

편집 : 모든 것이 런타임에 있어야합니다. 존재하지 않는 객체를 인스턴스화하거나 데이터를 채울 수없는 XSD 유형을 알 수 없습니다. 그래서 저는 xjc가 옵션이 아니라고 생각합니다.

+0

XSD는 XML을 작성하는 데 사용할 수있는 JDK와 함께 제공되는 도구를 사용하여 JAXB 클래스를 생성하는 데 사용할 수 있습니다. 여기에서 예제를 참조하십시오. http://docs.oracle.com/javase/ tutorial/jaxb/intro/examples.html – Adam

+0

이것은 [SO-1674902]와 중복 될 수 있습니다 (http://stackoverflow.com/questions/1674902/converting-csv-to-xml-with-an-xsd?rq= 1). C#에서의 구현은 단지 1 ~ 2 개의 XSD 만 고려했음을 인정해야합니다. 이제는 큰 것으로 만들고 싶었지만 분명히 해결책이 없습니다. – Sphaso

답변

2

출력 XML 파일에 XSD이 있으므로이 XML을 만드는 가장 좋은 방법은 Java Architecture for XML Binding (JAXB)을 사용하는 것입니다. 자습서의 "Using JAXB"을 참조하여 요구 사항에 맞게이를 사용하는 방법에 대한 개요를 제공 할 수 있습니다. 다음과 같이

기본 개념은 다음과 같습니다

  • , XML 스키마에서 JAXB 자바 클래스를 생성 자바 당신이 비 정렬 화하는
  • 를 사용하여 스키마 파생 JAXB 클래스와 정렬 화 XML의 내용이 그 XSD을 즉 응용 프로그램
  • 스키마 파생 JAXB 클래스를 사용하여 처음부터 Java 콘텐츠 트리를 만듭니다.
  • 출력을 XML 파일로 비 정렬 화합니다.

Here's another tutorial 정보를 찾을 수 있습니다.

+0

링크를 가져 주셔서 감사합니다.하지만이 기사에서는 xjc라는 도구를 사용하여 Java 클래스를 생성하는 방법을 보았습니다. JDK를 설치하지 않고 런타임에 모든 것을 처리해야합니다. 주요 아이디어는 어떤 종류의 XSD를 받을지 모르겠으므로 프로그래밍 방식으로 바인딩 할 수는 없습니다. 또는, 다시, 나는 틀린가? – Sphaso

+0

@Sphaso - 아니, 당신이 잘못한 것은 아니지만, jaxb는 당신이하려는 것을 이해하지 못합니다. jaxb는 _statically_ defined xsds에 유용합니다. – jtahlborn

0

이 작업은 아직 진행 중이지만 XSD를 통해 새 문서 트리를 찾을 때 요소를 다시 작성할 수 있습니다.

public void run() throws Exception { 
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 
    DocumentBuilder builder = factory.newDocumentBuilder(); 
    Document document = builder.parse(new InputSource(new FileReader(
      "schema.xsd"))); 

    Document outputDoc = builder.newDocument(); 

    recurse(document.getDocumentElement(), outputDoc, outputDoc); 

    TransformerFactory transFactory = TransformerFactory.newInstance(); 
    Transformer transformer = transFactory.newTransformer(); 
    StringWriter buffer = new StringWriter(); 
    transformer.transform(new DOMSource(outputDoc), 
      new StreamResult(buffer)); 
    System.out.println(buffer.toString()); 
} 

public void recurse(Node node, Node outputNode, Document outputDoc) { 

    if (node.getNodeType() == Node.ELEMENT_NODE) { 
     Element element = (Element) node; 
     if ("xs:element".equals(node.getNodeName())) { 
      Element newElement = outputDoc.createElement(element 
        .getAttribute("name")); 
      outputNode = outputNode.appendChild(newElement); 

      // map elements from CSV values here? 
     } 
     if ("xs:attribute".equals(node.getNodeName())) { 
      //TODO required attributes 
     } 
    } 
    NodeList list = node.getChildNodes(); 
    for (int i = 0; i < list.getLength(); i++) { 
     recurse(list.item(i), outputNode, outputDoc); 
    } 

} 
+0

이런 식으로 생각했습니다.하지만 몇 가지 문제가 있습니다. - 서로 다른 지점에 같은 노드 이름을 사용하면 어떨까요? 예 : (Xpath 표기)/root/branchOne/sameName -/root/branchTwo/sameName? xs : 요소 또는 xs : 특성을 어떻게 전달합니까? 사용자가 지정한 각 출력에 대해 foreach를 수행합니까? 그러나, 나는 당신의 코드에 대해 더 깊이 생각할 필요가있다. 한편, 감사합니다! – Sphaso

+0

@Sphaso 네, 동의합니다. 많은 일이 될 것입니다. – Adam

관련 문제