読者です 読者をやめる 読者になる 読者になる

「Java」XML ドキュメントを複製するサンプルコード

XML ドキュメントを複製するサンプルコードを書いてみたので、メモしておきます。

やり方としては、Node#cloneNode で複製元の XML ドキュメントからノードを複製して、Document#importNode で複製先の XML ドキュメントにインポートするという感じです。

・Node (Java Platform SE 8 )
https://docs.oracle.com/javase/jp/8/docs/api/org/w3c/dom/Node.html

・Document (Java Platform SE 8 )
https://docs.oracle.com/javase/jp/8/docs/api/org/w3c/dom/Document.html

( ※ 2015/10/24 修正 ) 非常にお恥ずかしいですが、Node#cloneNode はする必要なく Document#importNode だけで複製できるようです・・・

以下がサンプルになります。

■ XMLCloneTest.java

package xml;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

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

public class XMLCloneTest {
  public static void main(String[] args) throws Exception {
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    DocumentBuilder builder = factory.newDocumentBuilder();
    Document document = builder.newDocument();

    // 複製元の XML ドキュメントの作成
    Element root = document.createElement("root");
    document.appendChild(root);
    Element e1 = document.createElement("e1");
    root.appendChild(e1);
    e1.setAttribute("a1", "data1");
    e1.appendChild(document.createTextNode("hoge"));

    // ひとまず内容を表示
    printXML(document, "document");
    
    // XML ドキュメントの複製
    Document documentClone = builder.newDocument();
    //Node n = root.cloneNode(true);
    Node clone = documentClone.importNode(root, true);
    documentClone.appendChild(clone);
    
    // e1 要素のデータを変更してみる
    NodeList list = documentClone.getElementsByTagName("e1");
    list.item(0).setTextContent("uga");
    
    // それぞれの XML ドキュメントの内容を表示 ( 複製した側で内容を変更しても、複製元の内容は変わっていないことが確認できます )
    printXML(document, "document");
    printXML(documentClone, "documentClone");
  }
  
  private static void printXML(Document d, String name) throws Exception {
    TransformerFactory transformerFactory = TransformerFactory.newInstance();
    Transformer transformer = transformerFactory.newTransformer();
    transformer.setOutputProperty(OutputKeys.INDENT, "yes");
    DOMSource source = new DOMSource(d);
    StreamResult result = new StreamResult(System.out);
    System.out.println("----- " + name +  " -----");
    transformer.transform(source, result);
  }
}

■ 実行結果

----- document -----
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<root>
<e1 a1="data1">hoge</e1>
</root>
----- document -----
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<root>
<e1 a1="data1">hoge</e1>
</root>
----- documentClone -----
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<root>
<e1 a1="data1">uga</e1>
</root>


複製先の XML ドキュメントの内容を変更しても、複製元には影響ないことが確認できますね。

ちなみにサンプルの true としているのはノードの複製、インポートともに再帰的にやるためです。false とするとそのノードのみ複製、インポートされることになります。サンプルだと documentClone の XML ドキュメントが <root/> になります ( これじゃ XML ドキュメントの複製にはなりませんけどね・・・ )


簡単ですが、以上になります。

[ 環境情報 ]
Windows 7 SP1
Java SE 8 Update 25