2010-10-26 36 views
2

我可以使用「org.w3c.dom.Document」將節點從一個XML文件複製到另一個節點。 「
但是,我似乎無法重命名我正在複製的元素。將元素從一個XML文件複製並重命名爲Java中的另一個XML文件

我有類似:
File1.xml

<SomeCustomNode randomAttribute="aValue" another="10/10/2010"> 
    <Information> 
     <Yellow name="banana"/> 
     <Orange name="orange"/> 
     <Red name="strawberry"/> 
    </Information> 
    <Some> 
     <IgnoredNode/> 
    </Some> 
</SomeCustomNode> 

和這樣的事情:
FileList.xml

<ListOfNodes date="12/10/2010"> 
    <aCopy name="fruit" version="10"> 
     <Yellow name="banana"/> 
     <Orange name="orange"/> 
     <Red name="strawberry"/> 
    </aCopy> 
    <aCopy name="vegetables" version="3"> 
     <Yellow name="sweetcorn"/> 
     <Orange name="carrot"/> 
     <Red name="tomato"/> 
    </aCopy> 
</ListOfNodes> 

所以,我在做什麼正在一個節點(和孩子)從File1.xml並插入到FileList.xml,但重命名Element並向元素添加了一些屬性。
信息變得aCopy name="fruit" version="10"

我目前使用XPath表達式來獲得信息節點作爲節點列表(僅1個結果),然後導入到這文件2像這樣:

Document docFile1 = XMLDocumentStore.getDoc("/path/to/File1.xml"); 
Document docFileList = XMLDocumentStore.getDoc("/path/to/FileList.xml"); 
NodeList result = XPathAPI.selectNodeList(docFile1.getFirstChild(), ".//Information"); 
Node importNode = docFileList.importNode(result.item(0), true); 
// We want to replace aCopy fruit with the updated version found in File1 
NodeList fruitNode = XPathAPI.selectNodeList(docFileList.getFirstChild(), ".//aCopy[@name=\"fruit\"]"); 
Node replaceNode = fruitNode.item(0).getParentNode().replaceChild(importNode, fruitNode.item(0)); // probably a better way to do this 
// Now we want to replace the Element name as it is still set to Information 
docFileList.renameNode(replaceNode, null, "aCopy"); // Error: oracle.xml.parser.v2.XMLDOMException: cannot add attribute belonging to another element 

我如果我將代碼移動一點,得到其他錯誤,例如: 無法刪除或替換節點,它不是當前節點的子節點等。

通過XSLT會更好嗎?我所做的只是將特定的節點(它是子節點)並將其放入另一個XML文件,但替換元素名稱並添加2個屬性(包含值)。它將是每個文件(File1 ... File ###)的同一個節點,並且將以相同方式重命名,屬性值取自源文件(例如,File1.xml,對於我的示例)節點不會改變(在我的例子中,黃色,橙色,紅色)。
乾杯!

+1

這將是更適合於斯卡拉,具有原生XML支持。 XSLT是一個痛苦的世界,可以說比現在發現的更大。如果你很好奇,請訪問http://www.scala-lang.org/node/131 - 如果你不好奇,那麼我希望你在尋找答案時獲得好運。 – Synesso 2010-10-26 09:50:43

+3

我會推薦使用XSLT,特別是對於像這樣的簡單轉換。如果您正在處理大型XML文件,那麼使用DOM並不是一個很好的解決方案。 – gcores 2010-10-26 09:53:57

+0

@ Synesso - 雖然我可以在Java項目中使用Scala,但是,我被Scala吸引了,儘管我必須學習並且被我的團隊接受。將Scala添加到類/構建路徑,然後設置一個Scala類來與Java類交互? – dan2k3k4 2010-10-26 13:41:01

回答

1

爲什麼使用Oracle XML解析器?

如果您使用javax.xml提供的默認值,你不會得到這個錯誤:

import javax.xml.parsers.DocumentBuilderFactory; 
import org.w3c.dom.Document; 
import org.w3c.dom.Node; 
import org.w3c.dom.NodeList; 
import com.sun.org.apache.xpath.internal.XPathAPI; 

public static void main(String[] args) throws Exception { 

    Document docFile1 = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new File("File1.xml")); 
    Document docFileList = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new File("FileList.xml")); 
    NodeList result = XPathAPI.selectNodeList(docFile1.getFirstChild(), ".//Information"); 
    Node importNode = docFileList.importNode(result.item(0), true); 
    // We want to replace aCopy fruit with the updated version found in File1 
    NodeList fruitNode = XPathAPI.selectNodeList(docFileList.getFirstChild(), ".//aCopy[@name=\"fruit\"]"); 
    Node replaceNode = fruitNode.item(0).getParentNode().replaceChild(importNode, fruitNode.item(0)); // probably a better way to do this 
    // Now we want to replace the Element name as it is still set to Information 
    docFileList.renameNode(replaceNode, null, "aCopy"); 

    print(docFileList); 

} 

打印出:

<ListOfNodes date="12/10/2010"> 
    <Information> 
     <Yellow name="banana"/> 
     <Orange name="orange"/> 
     <Red name="strawberry"/> 
    </Information> 
    <aCopy name="vegetables" version="3"> 
     <Yellow name="sweetcorn"/> 
     <Orange name="carrot"/> 
     <Red name="tomato"/> 
    </aCopy> 
</ListOfNodes> 
+0

嗯,你說得對。似乎是我的進口問題。將不得不解決這個問題。我一直在基於已經存在的項目構建我的工具,但我可以交換輸入或修復它,僅用於這一個類。乾杯! – dan2k3k4 2010-10-26 13:33:32

相關問題