2012-09-01 24 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"> 

用戶給出規則

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

我在C#實現這使用數據集,如何coul d我在Java中執行它?我知道有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文件,因此創建此XML的最佳方法是使用Java Architecture for XML Binding(JAXB)。您可能想參考:"Using JAXB"教程,爲您提供如何使用此功能以滿足您的需求的概述。

的基本思路如下:

  • 生成XML模式JAXB Java類,即在XSD,你有
  • 使用模式派生JAXB類解組和編組XML內容在Java應用
  • 使用模式派生JAXB類
  • 解組數據,以你的輸出XML文件從頭開始創建Java內容樹。

Here's another tutorial您可能會發現內容豐富。

+0

謝謝你的鏈接,但我看到的是如何使用這個名爲xjc的工具來生成Java類。我需要在運行時做所有事情,可能沒有在用戶機器上安裝任何JDK。主要想法是我不知道我會收到什麼樣的XSD,所以我不能以編程方式給出任何綁定。或者,我又錯了嗎? – Sphaso

+0

@Sphaso - 不,你沒有錯,jaxb對你想要做的事沒有意義。 jaxb對於_statically_定義的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:element或xs:attribute?你是否對每個用戶指定的輸出進行foreach?但是,我可能需要更多地考慮您的代碼。同時,謝謝! – Sphaso

+0

@Sphaso是的,我同意,這將是很多工作。 – Adam