【Java入門】XMLをDOM、SAXで読み込み要素を取得する方法

こんにちは!フリーランスの長野です。

JavaでXMLファイルって使っていますか?

XMLファイルは項目と値のセットを人やソフトウェアが読み込めるように構成することができるので、データの保存や設定値を保存する場合によく使われます。

この記事では、XMLファイルの読み込み方法について

・XMLとは?
・DOMとは?SAXとは?

といった基本的な内容から、

・DOMで読み込む方法
・SAXで読み込む方法
・プロパティファイルやSerializationについて

など具体的な内容についても解説していきます。

今回はXMLファイルの読み込み方法について、わかりやすく解説します。

なお、Javaの記事については、こちらにまとめています。

目次

XMLとは?

XMLとは、Extensible Markup Languageの略です。

マークアップ言語ですので、WEBサイトのデザインで使われるHTMLと似ています。

マークアップ言語とは、タグと値のセットで作られ、文章を構造化する言語のことです。

HTMLはブラウザが読み込むためのタグで構成されていますが、XMLは人やソフトウェアが読み込めるように構成することができます。

以下はXMLファイルの簡単な例です。

Sample.xml:

<?xml version="1.0" encoding="UTF-8"?>
<info code="A0001">
    <name>Taro Yamada</name>
</info>

DOMとは?SAXとは?

XMLファイルを扱う際に、Javaでは操作するAPIが主に2つ用意されています。

DOMSAXです。

DOM

DOMはDocument Object Modelの略で、要素がノードで表され、ノードの関係がノードツリーで表されます

ツリー構成はパソコン内のフォルダやファイルにも用いられています。

SAX

SAXはSimple API for XMLの略で、要素を先頭から順にひとつずつイベントの連続として読み込みます。

DOMで読み込む方法

まずはDOMのAPIを使う方法について説明します。

準備とXMLの読み込み

javax.xml.parsersパッケージのDocumentBuilderクラスやDocumentBuilderFactoryクラスを使います。

次にorg.w3c.dom.Documentクラスを使ってXMLファイルを読み込みます。

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(new File("Sample.xml"));

タグ名と属性値の取得

それでは要素を取得する方法を説明します。

org.w3c.dom.ElementクラスのgetDocumentElementメソッドを使って要素を取得します。

ノードの名前を取得するにはgetNodeNameメソッドを、属性値を取得するにはgetAttributeメソッドを使います。

Element element = doc.getDocumentElement();
System.out.println("Node: " + element.getNodeName());
System.out.println("code: " + element.getAttribute("code"));

子ノードの取得

XMLではノード内にノードを記述することが多くあります。

org.w3c.dom.NodeListクラスで子ノードのリストを扱います。

子ノードのリストを取得するにはgetChildNodesメソッドを使います。

子ノードはorg.w3c.dom.Nodeクラスで扱います。

NodeList nodeList = element.getChildNodes();
for(int i = 0; i < nodeList.getLength(); i++) {
    Node node = nodeList.item(i);
    if(node.getNodeType() == Node.ELEMENT_NODE) {
        Element name = (Element)node;
        if(name.getNodeName().equals("name")) {
            System.out.println(name.getNodeName() + ": " + name.getTextContent());
        }
    }
}

サンプルコードまとめ

サンプルコードをまとめて実行結果を確認してみましょう。

読み取るXMLファイルは先ほどのSample.xmlを使います。

import java.io.File;
 
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
 
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
 
public class XMLsample {
 
    public static void main(String[] args) {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        try {
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document doc = builder.parse(new File("Sample.xml"));
 
            Element element = doc.getDocumentElement();
            System.out.println("Node: " + element.getNodeName());
            System.out.println("code: " + element.getAttribute("code"));
 
            NodeList nodeList = element.getChildNodes();
            for(int i = 0; i < nodeList.getLength(); i++) {
                Node node = nodeList.item(i);
                if(node.getNodeType() == Node.ELEMENT_NODE) {
                    Element name = (Element)node;
                    if(name.getNodeName().equals("name")) {
                        System.out.println(name.getNodeName() + ": " + name.getTextContent());
                    }
                }
            }
 
        } catch (Exception e) {
            e.printStackTrace();
        }
 
    }
 
}

実行結果:

Node: info
code: A0001
name: Taro Yamada

SAXで読み込む方法

次はSAXのAPIを使う方法について説明します。

準備とXMLの読み込み

同じようにXMLファイルを読み込む準備をします。

javax.xml.parsersパッケージのSAXParserクラスやSAXParserFactoryクラスを使います。

SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser parser = factory.newSAXParser();
parser.parse(new File("Sample.xml"), new SAXsample());

parseメソッドの第2引数でSAXsampleクラスのインスタンスを指定しています。

このSAXsampleクラスは自作のクラスでorg.xml.sax.helpers.DefaultHandlerクラスを継承しています。

org.xml.sax.helpers.DefaultHandlerクラスの継承について説明します。

DefaultHandlerクラスの継承

SAXのAPIの場合はorg.xml.sax.helpers.DefaultHandlerクラスを継承して、それぞれのイベントが発生した際の処理を記述します。

例えば、ドキュメントの読み込みが開始された場合は、startDocumentメソッドに記述した内容が処理実行されます。

また開始ノードに達した場合は、startElementメソッドに記述した内容が処理実行されます。

 
class SAXsample extends DefaultHandler{
    public void startDocument() {
        System.out.println("読み込み開始");
    }
 
    public void endDocument() {
        System.out.println("読み込み終了");
    }
 
    public void startElement(String uri, String localName, String qName, Attributes attributes) {
        System.out.println("Node: " + qName + " 開始");
        if(qName.equals("info")) {
            System.out.println(attributes.getQName(0) + ": " + attributes.getValue(0));
        }
    }
 
    public void endElement(String uri, String localName, String qName) {
        System.out.println("Node: " + qName + " 終了");
    }
 
    public void characters(char[] ch, int start, int length) {
        System.out.println(new String(ch, start, length));
    }
}

DefaultHandlerクラスのメソッドについては、こちらで詳しく解説していますので参考にしてください。

https://docs.oracle.com/javase/jp/8/docs/api/org/xml/sax/helpers/DefaultHandler.html

サンプルコードまとめ

サンプルコードをまとめて実行結果を確認してみましょう。

読み取るXMLファイルは先ほどのSample.xmlを使います。

 
import java.io.File;
 
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
 
import org.xml.sax.Attributes;
import org.xml.sax.helpers.DefaultHandler;
 
class XMLsample{
 
    public static void main(String[] args) {
        SAXParserFactory factory = SAXParserFactory.newInstance();
        try {
            SAXParser parser = factory.newSAXParser();
            parser.parse(new File("Sample.xml"), new SAXsample());
        } catch (Exception e) {
            // TODO 自動生成された catch ブロック
            e.printStackTrace();
        }
    }
 
}
 
class SAXsample extends DefaultHandler{
    public void startDocument() {
        System.out.println("読み込み開始");
    }
 
    public void endDocument() {
        System.out.println("読み込み終了");
    }
 
    public void startElement(String uri, String localName, String qName, Attributes attributes) {
        System.out.println("Node: " + qName + " 開始");
        if(qName.equals("info")) {
            System.out.println(attributes.getQName(0) + ": " + attributes.getValue(0));
        }
    }
 
    public void endElement(String uri, String localName, String qName) {
        System.out.println("Node: " + qName + " 終了");
    }
 
    public void characters(char[] ch, int start, int length) {
        System.out.println(new String(ch, start, length));
    }
}

実行結果:

読み込み開始
Node: info 開始
code: A0001
 
    
Node: name 開始
Taro Yamada
Node: name 終了
 
 
Node: info 終了
読み込み終了

プロパティファイルやSerializationについて

この記事ではXMLファイルをDOMやSAXのAPIを使って読み込む方法について解説しました。

JavaではXML形式のプロパティファイルJavaBeansクラスのオブジェクトデータをXML形式から読み込むこともできます。

こちらで詳しく解説していますのでぜひ参考にしてください。

まとめ

ここではXMLファイルの読み込み方法について説明しました。

XMLファイルは項目と値がセットになったデータを人やソフトウェアが読み込めるように構成することができるので便利です。

使いこなすことができるように、この記事を何度も参考にして下さいね!

この記事を書いた人

熊本在住のフリープログラマ兼ライターです。C/C++/C#、Java、Python、HTML/CSS、PHPを使ってプログラミングをしています。専門は画像処理で最近は機械学習、ディープラーニングにはまっています。幅広くやってきた経験を活かしてポイントをわかりやすくお伝えしようと思います。
お問合せはこちらでも受け付けています。
info@sss-lab.com

目次