1概要

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

XML文書を解析する方法は複数あります。この記事ではDOMの構文解析に焦点を当てます。 DOMパーサーは文書をロードし、メモリー内に階層ツリー全体を作成します。

JavaでのXMLライブラリサポートの概要については、以前のリンク/java-xml-libraries[article]を参照してください。


2私達の文書

この例で使用するXML文書から始めましょう。

<?xml version="1.0"?>
<tutorials>
    <tutorial tutId="01" type="java">
        <title>Guava</title>
        <description>Introduction to Guava</description>
        <date>04/04/2016</date>
        <author>GuavaAuthor</author>
    </tutorial>
...
</tutorials>

このドキュメントには、「tutorials」というルートノードと4つの「tutorial」子ノードがあります。これらはそれぞれ2つの属性を持っています:“ tutId”と“ type”です。また、各「チュートリアル」には、「title」、「description」、「date」、「author」の4つの子ノードがあります。

これで、この文書の構文解析を続けることができます。

3. XMLファイルを読み込む

まず、Apache XercesライブラリはJDKに同梱されているので、追加の設定は不要です。

XMLファイルのロードにすぐに入りましょう。

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

上記の例では、最初に

DocumentBuilder

クラスのインスタンスを取得してから、それを表す

Document

オブジェクトを取得するためにXMLドキュメントで

parse()

メソッドを使用します。

また、

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

    がDOMコンポーネント** の主要なデータ型であることに注意することが重要です。すべての要素、属性、テキストはノードと見なされます。

次に、

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<n; i++) {
        current = nodeList.item(i);
        if(current.getNodeType() == Node.ELEMENT__NODE) {
            System.out.println(
              current.getNodeName() + ": " + current.getTextContent());
        }
    }
}

まず、

getChildNodes()メソッドを使用して

NodeList__を取得し、それを反復処理して、ノード名とテキストの内容を出力します。

出力は私達の文書の最初の “tutorial”要素の内容を示します。

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"));
}

ここで、属性値を変更することは、

Element

s

setAttribute()

メソッドを呼び出すことの簡単なことです。


7. 新しい文書を作成する

DOMを変更するだけでなく、新しいXML文書を最初から作成することもできます。

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

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<users>
    <user id="1">
        <email>[email protected]</email>
    </user>
</users>

このXMLには、子ノード

email.

を持つ1つの

user

要素を持つ

users

ルートノードが含まれています。

これを達成するには、まず

Builder

s

newDocument()メソッドを呼び出して

Document__オブジェクトを返す必要があります。

次に、新しいオブジェクトの

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文書を作成、変更、保存する方法を学びました。

いつものように、例の完全なソースコードはhttps://github.com/eugenp/tutorials/tree/master/xml[GitHubに載っています]から入手できます。