2011-03-08 136 views
9

我的目的是将xml文件读入Dom对象,编辑dom对象,这涉及到删除一些节点。克隆dom.Document对象

完成此操作后,我希望将Dom恢复到原始状态而不实际解析XML文件。

是否有无论如何我可以克隆我解析XML文件后获得的dom对象的第一次。这个想法是为了避免一直读取和解析xml,只保留原始dom树的副本。

+0

的http://stackoverflow.com/questions/279154/how-can-i-clone-an-entire-document-using-the-java-dom – 2012-04-09 18:06:03

回答

5
TransformerFactory tfactory = TransformerFactory.newInstance(); 
Transformer tx = tfactory.newTransformer(); 
DOMSource source = new DOMSource(doc); 
DOMResult result = new DOMResult(); 
tx.transform(source,result); 
return (Document)result.getNode(); 

这将是使DOM文档的副本Java 1.5的解决方案。看看Transformer FactoryTransformer

+0

isEqualNode()不返回可能的欺骗如果以这种方式复制,则为true – ka3ak 2012-02-26 08:55:45

+0

此方法会保留副本中的处理说明和注释! – 2014-01-15 16:47:33

11

你可以在org.w3c.dom.Document中使用importNode API:

Node copy = document.importNode(node, true); 

完整的例子

import java.io.File; 

import javax.xml.parsers.DocumentBuilder; 
import javax.xml.parsers.DocumentBuilderFactory; 

import org.w3c.dom.Document; 
import org.w3c.dom.Node; 

public class Demo { 

    public static void main(String[] args) throws Exception { 
     DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
     DocumentBuilder db = dbf.newDocumentBuilder(); 

     Document originalDocument = db.parse(new File("input.xml")); 
     Node originalRoot = originalDocument.getDocumentElement(); 

     Document copiedDocument = db.newDocument(); 
     Node copiedRoot = copiedDocument.importNode(originalRoot, true); 
     copiedDocument.appendChild(copiedRoot); 

    } 
} 
+0

请注意,这种复制文档的方式将删除文件中的处理指令或注释! – 2014-01-15 16:46:34

+0

我相信这会删除任何附加到旧文档中任何节点的UserData!这是有道理的,但必须注意 – ParkerHalo 2016-08-09 10:14:21

3

你可以克隆树或仅具有DOM的节点cloneNode(boolean isDeepCopy)API。

Document originalDoc = parseDoc(); 
Document clonedDoc = originalDoc.cloneNode(true); 

不幸的是,因为cloneNode()上的文件(根据API)实现特定的,我们必须去防弹方法,那就是,创建一个新的文件,并导入克隆节点从原始文档:

... 
Document clonedDoc = documentFactory.newDocument(); 
cloneDoc.appendChild(
    cloneDoc.importNode(originalDoc.getDocumentElement(), true) 
); 

注意,没有操作是线程安全的,所以要么只能在本地使用它们,或者线程局部或同步它们。

0

我会坚持使用TransformerFactory的第二个建议。 使用importNode,您不会得到文档的完整副本。 标题未被复制。

<?xml version="1.0" encoding="UTF-8" standalone="no"?> 
<?aid style="50" type="snippet" readerVersion="6.0" featureSet="257" product="8.0(370)" ?>  
<?aid SnippetType="PageItem"?><Document DOMVersion="8.0" Self="d"> 

这将不会返回上面的,因为这是不可复制的。这将会使用你的新文档包含的内容。

<?xml version="1.0" encoding="UTF-8" standalone="no"?>