2010-10-26 37 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

相关问题