2013-01-17 23 views
2

給定一組三個XML文件:尋找應用XML補丁的Java工具/ Maven的

first.xml

<root> 
    <item1>A</item1> 
    <complexItem> 
     <item2>B</item2> 
     <item3>C</item2> 
    </complexItem> 
</root> 

patch1.xml

<root> 
    <item1>X</item1> 
</root> 

patch2.xml

<root> 
    <complexItem> 
     <item3>Y</item> 
    </complexItem> 
    <differentItem>Z</differentItem> 
<root> 

我想結束了在XML:

patched.xml在補丁

<root> 
    <item1>X</item1> 
    <complexItem> 
     <item2>B</item2> 
     <item3>Y</item2> 
    </complexItem> 
    <differentItem>Z</differentItem> 
</root> 

所以新元素添加劑和補丁已有的元素是破壞性的。這些添加和更新可以發生在文檔樹的任何級別。理想情況下,這將是一個maven插件,它可以將文件列表作爲參數,儘管是Java中的一個解決方案(即可用的庫 - 我試圖避免重新發明應該已經完成​​的東西!)因爲我可以自己寫插件。每個文件(基礎和補丁)將始終具有相同的根元素。


我應該補充,是沒有用的情況下,除去從樹中的元素(分層性質的我們的文件替換引起這是使用補丁的文件的應用程序出現錯誤的情況下)。我多花了一些時間尋找一個預先構建的工具或庫,但找不到合適的東西,所以就拿Andrew的建議來從頭開始用dom4j來構建一些東西。很熟悉的dom4j,但這裏的大致我想出(未經審查/錯誤處理/恰當評論等):

public void execute(){ 

    // Environment specific file loading removed 

    SAXReader reader = new SAXReader(); 
Document patchedDocument = null; 
for (InputStream is : loadedFiles) { 
    Document d = null; 
    try { 
     d = reader.read(is); 
    } catch (DocumentException e) { 
     e.printStackTrace(); 
    } 
    if (patchedDocument == null) { 
     patchedDocument = d; 
    } else { 
     Element root = d.getRootElement(); 
     patch(patchedDocument, root); 
    } 
} 

    // Environment specific file writing 

} 

private void patch(Document patchedDocument, Element element) { 

    for (Iterator i = element.elementIterator(); i.hasNext();) { 
     Element nextElement = (Element) i.next(); 
     if (nextElement.isTextOnly()) { 
      String path = nextElement.getUniquePath(); 
      Node n = patchedDocument.selectSingleNode(path); 
      if (n != null) 
      { 
           // This already exists and needs content replacing  
       n.setText(nextElement.getText()); 
      }else{ 
           // This doesn't exist and needs to be added to the tree 
       addElement(patchedDocument, nextElement); 
      } 
     } else { 
      patch(patchedDocument, nextElement); 
     } 
    } 
} 

private Node addElement(Document patchedDocument, Element element) 
{ 
    Element parent = element.getParent(); 
    String parentPath = parent.getPath(); 
    Node n = patchedDocument.selectSingleNode(parentPath); 
    if (n == null){ 
     return addElement(patchedDocument, parent); 
    } else { 
     ((Branch)n).add(element.detach()); 
     return n; 
    } 
} 
+0

你的意思是同時使用「complexType」和「complexItem」,或者是一個錯字? –

+0

錯字 - 將修復 –

+0

這裏有一個類似的頁面:http://stackoverflow.com/questions/80609/merge-xml-documents,它是非常詳細的,你可以開發一個輕量級的基礎上。 –

回答

0

如果文件足夠小,以適應在內存中,我會寫一些Java代碼將它們全部分散到單獨的DOM中,然後根據您所描述的添加/破壞性邏輯將它們合併到一個DOM中,然後將合併的DOM吐出到目標文件中。有幾個Java庫可用於讀取和寫入XML文件,例如, DOM4J。您不希望自己試圖解析或構建XML。