parseXmlメソッドを実装する

 今回のアプリでパース対象となるRSSとして、ITproトップページのRSSを採用している。下記がそのURLである。

http://itpro.nikkeibp.co.jp/rss/ITpro.rdf

 RSSファイルはいくつかのセッションから構成されている。以下は、そのなかのアイテムセッションから、アイテムの一つ(つまり、個別の記事データ)を抜粋した例だ。(リスト3

<item rdf:about="http://itpro.nikkeibp.co.jp/article/COLUMN/20091212/342015/">
<title>Androidの仕組みを知る(3)(Android徹底解説---内部構造,移植,開発)</title>
<link>http://itpro.nikkeibp.co.jp/article/COLUMN/20091212/342015/</link>
<description> 最後に,アプリケーションが実行されるときのAndroidの内部的な動きを解説しよう。電話帳,カメラ,カレンダなど,Android携帯のユーザーが実際に操作するプログラムは,すべてこのアプリケーション層に入る。</description>
<dc:date>2009-12-16T00:00:00+09:00</dc:date>
</item>

 各アイテムはそれぞれ、以下の四つの要素で構成される。

・title
・link
・description
・dc:date

 今回実装するXMLパーサーでは、そのうち、titleとdescriptionの二つを取り扱うことにする。

 では、parseXmlメソッドの中身を見ていこう(リスト4)。

// XMLをパースする
public RssListAdapter parseXml(InputStream is) throws IOException, XmlPullParserException {
	XmlPullParser parser = Xml.newPullParser();
	try {
		parser.setInput(is, null);
		int eventType = parser.getEventType();
		Item currentItem = null;
		while (eventType != XmlPullParser.END_DOCUMENT) {
			String tag = null;
			switch (eventType) {
				case XmlPullParser.START_TAG:
					tag = parser.getName();
					if (tag.equals("item")) {
						currentItem = new Item();
					} else if (currentItem != null) {
						if (tag.equals("title")) {
							currentItem.setTitle(parser.nextText());
						} else if (tag.equals("description")) {
							currentItem.setDescription(parser.nextText());
						}
					}
					break;
				case XmlPullParser.END_TAG:
					tag = parser.getName();
					if (tag.equals("item")) {
						mAdapter.add(currentItem);
					}
					break;
			}
			eventType = parser.next();
		}
	} catch (Exception e) {
		e.printStackTrace();
	}
	return mAdapter;
}

 XmlPullParserの仕組みは至極単純だ。パースの対象となるXMLを頭から解析していき、各イベントに対し個別に処理を実行する。イベントの種類は「eventType」という変数の中身により、XML文書の始端と終端、そして各データの開始要素と終了要素に区別される。

 要素名はXmlPullParser.getNameメソッドで取得し、例えば、読み取りの対象となる要素名が「item」という名の開始要素に一致する場合、「currentItem」というItemオブジェクトの変数を生成する。要素名が「title」であればtitle要素の値を取得し、「description」であればdescription要素の値を取得する。

 そうやって各データがセットされたcurrentItemは、パーサーがitemの終了要素に達した時点でアダプタに追加される。この処理は順次繰り返され、XML文書の終端まで辿り着いた時点で全ての処理を終了する。このように、XmlPullParserを使うメリットとしては、「パフォーマンス」の面だけでなく、「使いやすさ」の面も特筆に値する。

 では、実機上での挙動を確認してみよう。の左側は「Now Loading...」ダイアログを表示しているところ。右側はパースの結果をメインスレッド上でListViewにセットし、画面描画したところだ。

図●「Now Loading...」表示中(左)と、メインスレッドで画面描画した状態
図●「Now Loading...」表示中の画面(左)と、メインスレッドで画面描画した状態
[画像のクリックで拡大表示]

 RssParserTask内部での処理の流れがお分かりいただけただろうか。現段階では、記事ごとに詳細画面を表示する「ItemDetailActivity.java」が未実装なので、リストの項目を選択しても何も変化しないが、それについては次回の記事で説明しよう。

 以上、Androidにおけるスレッド処理と、XMLのパース方法について解説してきた。最終回となる次回は、ItemDetailActivity.javaの実装を通して「Intent」の概念を解説するとともに、その他細かな機能を追加してアプリケーションを完成させていく。

中川善樹(なかがわよしき)
アシアル株式会社 エンジニア
中川善樹(なかがわよしき)Web開発,中でもPHPでの開発に目覚めアシアルに入社。現在ではPHPでのシステム開発に加え,Ajax技術を用いたRIA(rich internet application)開発,iPhoneやAndroidなどのスマートフォン開発も手がけ,ユーザビリティの高いサイト作りに気を配る。Android版の「Abacus」など,最新のアプリケーションをいち早く市場に投入することを目指している。