Java
dom

JDOMでXMLを読み込んでみる

DOMとは

XMLを読み込む便利ライブラリです。
詳しい概要はこちら

SpringMVC下で動かしてるので、汎用性はさっぱり無いです。
そんな特殊な環境は知らんのじゃー!って人はこっちをどうぞ

Spring使いの人は
Spring IOで依存性の管理をしてくれるみたいなので、早速使ってみましょう。

Mavenにライブラリを追加

pom.xml
    <!-- JDOM -->
    <dependency>
        <groupId>org.jdom</groupId>
        <artifactId>jdom2</artifactId>
    </dependency>

毎度のことながらバージョン管理はSpring IOです。

XMLの読み込みをしてみる。

Webサービスを想定して(しなくても全然いいけど)
XMLを読み込んでみます。

サンプルに使うXMLはこれ

sample.xml
<?xml version="1.0" encoding="UTF-8"?>
<employees>
    <employee>
        <name>Yamamoto</name>
        <class>Sales Section1</class>
        <sex>male</sex>
        <age>10</age>
    </employee>

    <employee>
        <name>Hanako</name>
        <class>Sales Section2</class>
        <sex>female</sex>
        <age>20</age>
    </employee>

        <employee>
        <name>Taniguchi</name>
        <class>Develop Section2</class>
        <sex>male</sex>
        <age>30</age>
    </employee>

</employees>

これをsrc/main/resourceにおいて取得してみます。

DomController.java
    @Autowired
    ResourceLoader resourceLoader;

    @RequestMapping(value="/readable")
    public String readable() {

        //ファイル取得
        Resource resource = resourceLoader.getResource("classpath:sample.xml");

        Document doc = null;
        Element root = null;

        //Xml取得
        try {
            doc = new SAXBuilder().build(resource.getFile());
            root = doc.getRootElement();

            } catch (JDOMException e) {
                System.out.println(e);
            } catch (IOException e) {
                // TODO 自動生成された catch ブロック
                System.out.println(e);
            }

こっからはSpringのコードが混じります
普通のサンプルだったらresource.getFile()new File("hogehoge.xml")になってるかと

やってることは

DomController.java
            doc = new SAXBuilder().build(resource.getFile());
            root = doc.getRootElement();

ここでルートの要素を取得しているだけです。

子要素を取得してみる

DomController.java
        //Xmlから子要素を取得(孫要素は取得していない)
        List<Element> list = root.getChildren();

今回は子要素が3つあるので、Listになります。

孫要素の値を取得してみる。

employee下にあるnameの値を取得してみます。
getValue()getAttribute("hoge_name")とかに変えれば属性の値も取得できます。
孫、ひ孫と属性が増えるたびにループが増える訳ですね。
(ここら辺以降は”木”の探索の技術かな。)

DomController.java
        List<String> result = new ArrayList<String>();

        //Xmlから孫要素を取得するループ
        for(Element e : list) {
            if(e.getName().compareTo("employee") == 0) {
                result.add(e.getChild("name").getValue());
            }
        }

        //取得した要素をコンソールに吐き出すループ
        for(String name : result) {
            System.out.println(name);
        }

最終的な完成系はこれ

DomController.java
@RestController
public class DomController {

    @Autowired
    ResourceLoader resourceLoader;

    @RequestMapping(value="/readable")
    public String readable() {

        //ファイル取得
        Resource resource = resourceLoader.getResource("classpath:sample.xml");

        Document doc = null;
        Element root = null;

        //Xml取得
        try {
            doc = new SAXBuilder().build(resource.getFile());
            root = doc.getRootElement();

            } catch (JDOMException e) {
                System.out.println(e);
            } catch (IOException e) {
                // TODO 自動生成された catch ブロック
                System.out.println(e);
            }

        //Xmlから子要素を取得(孫要素は取得していない)
        List<Element> list = root.getChildren();

        List<String> result = new ArrayList<String>();

        //Xmlから孫要素を取得するループ
        for(Element e : list) {
            if(e.getName().compareTo("employee") == 0) {
                result.add(e.getChild("name").getValue());
            }
        }

        //取得した要素をコンソールに吐き出すループ
        for(String name : result) {
            System.out.println(name);
        }

        return null;
    }

別に@RestControllerでなくても@Controllerでもなんの問題もないですね。

動かしてみる

ブラウザからアクセスして動作確認してみましょう。

image.png

コンソール画面

image.png

XMLからnameの値が取得出ているのが確認できますね