java-beginner.com ブログ

プログラミングを学習するブログ(Javaをメインに)

org.w3c.domパッケージでXMLの要素を検索

投稿日:

最終更新日:2016年09月07日

アイキャッチ

こんにちは。「Javaを復習する初心者」です。

今回はXMLの要素を検索する方法を試しました。

XMLの要素名とアトリビュートを指定して、検索することができます。

XMLファイル

検索するXMLファイルの内容は以下です。

HelloDOMsearch.xml

<?xml version="1.0"?>
<students>
  <student>
    <name class="family">family name 1</name>
    <name class="first">first name 1</name>
    <age>16</age>
  </student>
  <student>
    <name class="family">family name 2</name>
    <name class="first">first name 2</name>
    <age>17</age>
  </student>
  <student>
    <name class="family">family name 3</name>
    <name class="first">first name 3</name>
    <age>18</age>
  </student>
</students>

前回とほとんど同じです。student要素がひとつ増えただけです。

プログラム

このXMLファイルからname要素でclass属性が「family」であるものを検索し、要素の内容を出力するのが今回の目的です。

ソース

import java.io.IOException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class HelloDOMsearch {

    public static void main(String[] args) {

        Document document = getDocument();

        XPathFactory factory = XPathFactory.newInstance();
        XPath path = factory.newXPath();

        XPathExpression expression = null;
        try {
            expression = path.compile("//name[@class='family']");
        } catch (XPathExpressionException e) {
            e.printStackTrace();
        }

        NodeList nodeList = null;
        try {
            nodeList = (NodeList)expression.evaluate(document, XPathConstants.NODESET);
        } catch (XPathExpressionException e) {
            e.printStackTrace();
        }

        for (int i = 0; i < nodeList.getLength(); i++) {
            System.out.println(nodeList.item(i).getTextContent().substring("family".length() + 1));
        }

    }

    private static Document getDocument() {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = null;
        try {
            builder = factory.newDocumentBuilder();
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        }
        Document document = null;
        try {
            document = builder.parse("resource/HelloDOMsearch.xml");
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return document;
    }

}

結果

name 1
name 2
name 3

XMLを読み込む部分は前回と同じです。ファイル名が異なるだけなので、getDocument()メソッドにまとめました。Documentクラスを返却するメソッドです。

要素の検索をするには最初にXPathFactoryクラスのインスタンスを取得します。XPathFactoryインスタンスを使用して、XPathオブジェクトを作成するという手順です。XPathFactory#newInstance()メソッドを呼び出し、XPathFactoryインスタンスを取得します。このメソッドはstaticです。次に、 XPathFactory#newXPath()メソッドを使い、XPathクラスのインスタンスを取得します。

XPathクラスには compile()というメソッドがあります。このメソッドの引数はString型で文字列からXPathExpressionクラスのインスタンスを生成します。そして、XPathExpressionクラスにはevaluate()というメソッドがあり、このメソッドでノードが取得できます。

この一連の手順は本を見ながら記述しました。

XPathクラス#compile()メソッドに指定する引数は、今回は”//name[@class=’family’]”です。この書き方でname要素でclass属性が「family」という条件になるようです。取得したNodeListに対してNodeList#item()メソッドを使うことで要素を取得できます。ただし、getTextContent()の結果は属性を含む形式なのでsubstringで出力結果を調節しました。