2011年3月22日火曜日

AndroidでXMLを読み込む(ユーティリティを使ったSAXパーサ)

AndroidでのXMLの読み込み方法は、

  1. SAX
  2. DOM
  3. XMLプルパーサ
がある。

今回は、1.SAXを使用した。

SAXでのXMLの解析は、
処理の大部分はハンドラに記述するわけだけど、
対象のXMLがネストの深い構造だったりすると、途端にソースの可読性が下がる。
(私がまだ綺麗な書き方を知らないだけかもしれない…)

AndroidでSAXを扱う場合、
android.saxパッケージにユーティリティクラスが用意されている。これホントに便利。
プルパーサに書き換えようと思っていたけど、とりあえずはこっちでいいかも。

※参考
AndroidでXMLを扱う
http://www.ibm.com/developerworks/jp/xml/library/x-android/



要素の属性を取得する場合は、
StartElementListenerTextlementListenerを使用する必要がある。
<xml>
<root>
<tag id="A001">data</tag>
</root>
みたいなものには、

public List<Data> parse() {
    final Data currentData = new Data();
    List<Data> list = new ArrayList<Data>();

    RootElement root = new RootElement("root");
    Element tag = root.getChild("tag");
    tag.setTextElementListener( new TextElementListener() {
        @Override
        public void start(Attributes attributes) {
            // id属性を取得
            String id = attributes.getValue("id");
            currentData.setId(id);
        }

        @Override
        public void end(String body) {
            // tag要素を取得
            currentData.setData(body);
            list.add(new Data(currentData));
        }
    });
    try {
        Xml.parse(getInputStream(), Xml.Encoding.UTF_8, root.getContentHandler());
        return list;
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

最初はよく理解せず、
ElementListenerとEndTextElementListenerを組み合わせていたけど、
リスナの呼び出し順が、
  1. ElementListener$start
  2. ElementListener$end
  3. EndTextElementListener$end
で、当然意図していたのと違っていた。(2と3が逆だと思った)

Simple Typeの要素にはTextElementListenerを、
Complex Typeの要素にはElementListenerを設定してあげるのが正しいやり方。

0 件のコメント: