如何在 Java 中将 DOM 节点从一个文档复制到另一个文档?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/873247/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 20:30:28  来源:igfitidea点击:

How do I copy DOM nodes from one document to another in Java?

javaapidomcopy

提问by

I'm having trouble with copying nodes from one document to another one. I've used both the adoptNode and importNode methods from Node but they don't work. I've also tried appendChild but that throws an exception. I'm using Xerces. Is this not implemented there? Is there another way to do this?

我在将节点从一个文档复制到另一个文档时遇到问题。我已经使用了 Node 中的 AdoptNode 和 importNode 方法,但它们不起作用。我也试过 appendChild 但这会引发异常。我正在使用 Xerces。这不是在那里实施吗?有没有另一种方法可以做到这一点?

List<Node> nodesToCopy = ...;
Document newDoc = ...;
for(Node n : nodesToCopy) {
    // this doesn't work
    newDoc.adoptChild(n);
    // neither does this
    //newDoc.importNode(n, true);
}

采纳答案by Jherico

The problem is that Node's contain a lot of internal state about their context, which includes their parentage and the document by which they are owned. Neither adoptChild()nor importNode()place the new node anywhere in the destination document, which is why your code is failing.

问题是 Node 包含很多关于它们的上下文的内部状态,包括它们的出身和拥有它们的文档。既不将新节点adoptChild()importNode()放置在目标文档中的任何位置,这就是您的代码失败的原因。

Since you want to copy the node and not move it from one document to another there are three distinct steps you need to take...

由于您想复制节点而不是将其从一个文档移动到另一个文档,因此您需要采取三个不同的步骤......

  1. Create the copy
  2. Import the copied node into the destination document
  3. Place the copied into it's correct position in the new document
  1. 创建副本
  2. 将复制的节点导入到目标文档中
  3. 将复制的放在新文档中的正确位置
for(Node n : nodesToCopy) {
    // Create a duplicate node
    Node newNode = n.cloneNode(true);
    // Transfer ownership of the new node into the destination document
    newDoc.adoptNode(newNode);
    // Make the new node an actual item in the target document
    newDoc.getDocumentElement().appendChild(newNode);
}

The Java Document API allows you to combine the first two operations using importNode().

Java 文档 API 允许您使用importNode().

for(Node n : nodesToCopy) {
    // Create a duplicate node and transfer ownership of the
    // new node into the destination document
    Node newNode = newDoc.importNode(n, true);
    // Make the new node an actual item in the target document
    newDoc.getDocumentElement().appendChild(newNode);
}

The trueparameter on cloneNode()and importNode()specifies whether you want a deep copy, meaning to copy the node and all it's children. Since 99% of the time you want to copy an entire subtree, you almost always want this to be true.

true对参数cloneNode()importNode()指定是否需要深拷贝,这意味着复制节点和所有它的孩子。由于 99% 的情况下您都希望复制整个子树,因此您几乎总是希望这是真的。

回答by Uri

adoptChild does not create a duplicate, it just moves the node to another parent.

AdoptChild 不会创建副本,它只是将节点移动到另一个父节点。

You probably want the cloneNode() method.

您可能需要 cloneNode() 方法。