Powered by SmartDoc

付録:DOMを用いた読み込み

DOM(Document Object Model)はW3Cの定めた標準のXML操作用APIです。Javaだけではなく、いろいろな言語を想定して設計しているため多少扱いづらいところがあります。しかし、XMLを本格的に扱うには必須のAPIです。詳しくは、XML関係の書籍か、Webサイトを参照してください。

リスト[ReadByDOM.java]は、今回のサンプルデータリスト[XMLデータ]を読み込むプログラムです。主な流れは、

  1. DOMパーサーを作成
  2. XMLファイルを読み込んでDOMを構築
  3. 出来たDOMからDataItemオブジェクトを作成
  4. 結果表示

のようになっています。

ReadByDOM.java
import javax.xml.parsers.*;
import org.w3c.dom.*;
import org.xml.sax.SAXException;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.ArrayList;

public class ReadByDOM {

    // 注:エラー処理は全くやってません

    public static void main(String[] args) throws Exception {
	//データを読んで
	DataItem [] items = getDataItems("data.xml");
	//表示
	for (int i=0;i<items.length;i++) {
	    System.out.println("Name["+items[i].getName()+"]");
	    System.out.println("Cost["+items[i].getCost()+"]");
	    System.out.println("Note["+items[i].getNote()+"]");
	    System.out.println("--------");
	}
    }

    // filename -> DataItem配列
    static DataItem [] getDataItems(String filename) {
	return interpretDatas( getDocument(filename).getDocumentElement() );
    }

    // XMLルート要素 -> DataItem配列
    static DataItem [] interpretDatas(Element root) {
	Element [] dataItemNodes = getElements(root,"dataItem");
	List items = new ArrayList();
	for (int i=0;i<dataItemNodes.length;i++) {
	    items.add( interpretItem( dataItemNodes[i] ));
	}
	DataItem [] ret = new DataItem[items.size()];
	return (DataItem[])items.toArray(ret);
    }

    // XML1データ -> DataItem
    static DataItem interpretItem(Element itemNode) {
	String name = getText(itemNode,"name");
	int cost = Integer.parseInt(getText(itemNode,"cost"));
	String note = getText(itemNode,"note");
	return new DataItem(name,cost,note);
    }


    //=======  以下汎用部品


    // XML テキストデータ取り出し
    static String getText(Element element,String name) {
	return getElements(element,name)[0].getFirstChild().getNodeValue();
    }

    // 指定したタグを取り出す
    static Element [] getElements(Element parent,String tagName) {
	NodeList list = parent.getElementsByTagName(tagName);
	List entry = new ArrayList();
	for (int i=0;i<list.getLength();i++) {
	    if (list.item(i) instanceof Element) {
		entry.add(list.item(i));
	    }
	}
	Element [] ret = new Element[entry.size()];
	return (Element[])entry.toArray(ret);
    }

    // JAXP API
    static DocumentBuilder getDocumentBuilder() {
        DocumentBuilderFactory dbf =
            DocumentBuilderFactory.newInstance();
        dbf.setValidating(false);
        try {
            return dbf.newDocumentBuilder();
        } catch (ParserConfigurationException e) {
	    e.printStackTrace();
        }
	System.exit(1);
	return null;
    }

    // JAXP API
    static Document getDocument(String filename) {
        try {
            return getDocumentBuilder().parse(new File(filename));
        } catch (SAXException e) {
	    e.printStackTrace();
        } catch (IOException e) {
	    e.printStackTrace();
        }
	System.exit(1);
	return null;
    }

}
実行結果
java ReadByDOM

Name[コーヒー]
Cost[120]
Note[主食]
--------
Name[チョコレート]
Cost[180]
Note[オヤツ]
--------
Name[ノート]
Cost[150]
Note[いつでもどこでもアイデアを記録]
--------