XercesによるDOM解析

DOM解析を使用してJavaでXMLファイルを操作する

1. 概要

このチュートリアルでは、XMLを解析/操作するための成熟した確立されたライブラリであるApache Xercesを使用してDOMを解析する方法について説明します。

XMLドキュメントを解析するための複数のオプションがあります。この記事では、DOMの解析に焦点を当てます。 DOMパーサーはドキュメントをロードし、メモリ内に階層ツリー全体を作成します。

JavaでのXMLライブラリのサポートの概要については、以前のarticleを確認してください。

2. 私たちのドキュメント

この例で使用するXMLドキュメントから始めましょう。



    
        Guava
        Introduction to Guava
        04/04/2016
        GuavaAuthor
    
...

このドキュメントには、4つの「チュートリアル」子ノードを持つ「チュートリアル」というルートノードがあることに注意してください。 これらにはそれぞれ「tutId」と「type」という2つの属性があります。 また、各「チュートリアル」には、「タイトル」、「説明」、「日付」、「著者」の4つの子ノードがあります。

これで、このドキュメントの解析を続行できます。

3. XMLファイルの読み込み

まず、the Apache Xerces library is packaged with the JDKに注意する必要があるため、追加の設定は必要ありません。

XMLファイルのロードに取り掛かりましょう。

DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document doc = builder.parse(new File("src/test/resources/example_jdom.xml"));
doc.getDocumentElement().normalize();

上記の例では、最初にDocumentBuilderクラスのインスタンスを取得し、次にXMLドキュメントでparse()メソッドを使用して、それを表すDocumentオブジェクトを取得します。

また、normalize()メソッドを使用して、ドキュメント階層がノード内の余分な空白や新しい行の影響を受けないようにする必要があります。

4. DOMの解析

それでは、XMLファイルについて見ていきましょう。

タグ「tutorial」を持つすべての要素を取得することから始めましょう。 これは、NodeList:を返すgetElementsByTagName()メソッドを使用して行うことができます。

@Test
public void whenGetElementByTag_thenSuccess() {
    NodeList nodeList = doc.getElementsByTagName("tutorial");
    Node first = nodeList.item(0);

    assertEquals(4, nodeList.getLength());
    assertEquals(Node.ELEMENT_NODE, first.getNodeType());
    assertEquals("tutorial", first.getNodeName());
}

Node is the primary datatype for the DOM componentsに注意することが重要です。 すべての要素、属性、テキストはノードと見なされます。

次に、getAttributes()を使用して最初の要素の属性を取得する方法を見てみましょう。

@Test
public void whenGetFirstElementAttributes_thenSuccess() {
    Node first = doc.getElementsByTagName("tutorial").item(0);
    NamedNodeMap attrList = first.getAttributes();

    assertEquals(2, attrList.getLength());

    assertEquals("tutId", attrList.item(0).getNodeName());
    assertEquals("01", attrList.item(0).getNodeValue());

    assertEquals("type", attrList.item(1).getNodeName());
    assertEquals("java", attrList.item(1).getNodeValue());
}

ここでは、NamedNodeMapオブジェクトを取得し、item(index)メソッドを使用して各ノードを取得します。

すべてのノードについて、getNodeName()getNodeValue()を使用してそれらの属性を見つけることができます。

5. トラバースノード

次に、DOMノードをトラバースする方法を見てみましょう。

次のテストでは、最初の要素の子ノードをトラバースして、それらのコンテンツを出力します。

@Test
public void whenTraverseChildNodes_thenSuccess() {
    Node first = doc.getElementsByTagName("tutorial").item(0);
    NodeList nodeList = first.getChildNodes();
    int n = nodeList.getLength();
    Node current;
    for (int i=0; i

まず、getChildNodes()メソッドを使用してNodeListを取得し、それを反復処理して、ノード名とテキストコンテンツを出力します。

出力には、ドキュメントの最初の「チュートリアル」要素の内容が表示されます。

title: Guava
description: Introduction to Guava
date: 04/04/2016
author: GuavaAuthor

6. DOMの変更

DOMに変更を加えることもできます。

例として、type属性の値を「java」から「other」に変更してみましょう。

@Test
public void whenModifyDocument_thenModified() {
    NodeList nodeList = doc.getElementsByTagName("tutorial");
    Element first = (Element) nodeList.item(0);

    assertEquals("java", first.getAttribute("type"));

    first.setAttribute("type", "other");
    assertEquals("other", first.getAttribute("type"));
}

ここで、属性値の変更は、ElementsetAttribute()メソッドを呼び出すだけの簡単な問題です。

7. 新しいドキュメントの作成

DOMの変更に加えて、新しいXMLドキュメントを最初から作成することもできます。

まず、作成するファイルを見てみましょう。



    
        [email protected]
    

XMLには、usersルートノードと、子ノードemail.を持つ1つのuser要素が含まれています。

これを実現するには、最初にDocumentオブジェクトを返すBuildernewDocument()メソッドを呼び出す必要があります。

次に、新しいオブジェクトのcreateElement()メソッドを呼び出します。

@Test
public void whenCreateNewDocument_thenCreated() throws Exception {
    Document newDoc = builder.newDocument();
    Element root = newDoc.createElement("users");
    newDoc.appendChild(root);

    Element first = newDoc.createElement("user");
    root.appendChild(first);
    first.setAttribute("id", "1");

    Element email = newDoc.createElement("email");
    email.appendChild(newDoc.createTextNode("[email protected]"));
    first.appendChild(email);

    assertEquals(1, newDoc.getChildNodes().getLength());
    assertEquals("users", newDoc.getChildNodes().item(0).getNodeName());
}

各要素をDOMに追加するために、appendChild()メソッドも呼び出しています。

8. ドキュメントの保存

ドキュメントを変更するか、最初から作成した後、ファイルに保存する必要があります。

まず、DOMSourceオブジェクトを作成し、次に単純なTransformerを使用してドキュメントをファイルに保存します。

private void saveDomToFile(Document document,String fileName)
  throws Exception {

    DOMSource dom = new DOMSource(document);
    Transformer transformer = TransformerFactory.newInstance()
      .newTransformer();

    StreamResult result = new StreamResult(new File(fileName));
    transformer.transform(dom, result);
}

同様に、コンソールでドキュメントを印刷できます。

private void printDom(Document document) throws Exception{
    DOMSource dom = new DOMSource(document);
    Transformer transformer = TransformerFactory.newInstance()
        .newTransformer();

    transformer.transform(dom, new StreamResult(System.out));
}

9. 結論

この簡単な記事では、Xerces DOMパーサーを使用してXMLドキュメントを作成、変更、保存する方法を学びました。

いつものように、例の完全なソースコードはover on GitHubで入手できます。