AndroidアプリでXMLを読み込んで分析する方法は?
Androidアプリで、XMLファイルを分析して何かをする、というアプリを考えている方も多いと思います。
例えば、WebサービスAPIを利用したい、という事であれば、XMLの分析は必須の技術です。
(WebサービスAPIとは、楽天、アマゾン、リクルート等など、色んな業者が提供してくれているものですが、ここではその説明は省きます。)
では、AndroidでのXMLの読み込み、分析をする為の、私が行っている手順を紹介します。
まず、以下の2つのクラスをインポートさせておきます。
import org.xmlpull.v1.XmlPullParser;
import android.util.Xml;
WebサービスAPIを利用するときであれば、HTTP通信でXMLファイルを読み込んで、InputStreamインスタンスを取得する、という方法を取ると思いますが、今回の説明では、既にXMLファイルをInputStreamインスタンスに読み込んでいるという前提で話を進めます。
1.以下のように、XmlPullParserインスタンスを取得します。
XmlPullParser xmlPullParser = Xml.newPullParser();
XmlPullParserは、XMLの要素を次々に読み込んでいくための機能が提供されたクラスと思ってください。
2.以下のように、XmlPullParserにXMLファイルが読み込まれているInputStreamを設定する。
xmlPullParser.setInput(is, “UTF-8”);
※第一引数のisはInputStreamインスタンス
第二引数はXMLファイルのエンコードを指定してください。
さて、これでXMLを分析していく準備が整いました。
あとはやりたい事に沿って、読み込んでいくのですが、ここでは、以下のような想定で読み込んでいく、という事にします。
・XMLファイルの最初から最後までで、nameタグの値(Value)の一覧を取得する。
「nameタグの値」とは、以下のxxxの部分です。
<name>xxx</name>
まず、サンプルコードを示します。
スポンサーリンク
String a[] = new String[]();
int counter = 0;
for(int e = xmlPullParser.getEventType(); e != XmlPullParser.END_DOCUMENT; e = xmlPullParser.next()){
if(e == XmlPullParser.START_TAG && xmlPullParser.getName().equals(“name”)){
a[counter] = xmlPullParser.nextText();
counter++
}
}
最低限のコードしか書いてませんが、こんな感じです。
xmlPullParserは、XMLを、1行毎とか1要素毎とかではなくて、ホントに一つずつ丁寧に読み込んでいきます。
開始タグ、値、終了タグがあれば、XmlPullParser.next()を使った場合、開始タグ⇒値⇒終了タグと進んでいく仕組みです。
これは、便利か不便か、どっちでしょうね。
私は最初戸惑いました。
forループを見ますと、xmlPullParser.getEventType()を初期値としています。
この時点では、xmlPullParserはInputStreamを設定したばかりですので、getEventType()の値は、開始を意味する「START_DOCUMENT」になっています。
ループの終了条件は、最後を意味する「END_DOCUMENT」になるまで、です。
ループの度に、XmlPullParser.next()を実行して次へ次へと進んでいく。
というループです。
これにより、XMLファイルの最初から最後まで読み込んでいく、という事が出来ます。
次はループの内部の説明です。
if文の条件に関して説明します。
簡単に言うと、「nameタグの開始タグである場合」という意味です。
欲しいのは、nameの開始タグと終了タグで囲まれた「値」なのですが、その「値」自身がxmlPullParserのカレントになっている状態では、値は取れますが、そもそもそれが何のタグで囲まれていたのかが、取れないのです。(getName()の戻り値がnullになる。)
というわけで、nameタグの開始タグがカレントになっているときに、次の要素の文字列を取る、という事で、if文の中で、nextText()を使います。
これは、次の要素をString型として取得する、というメソッドです。
他にもやり方はありますので、必ずしも上記がいい例なのかはわかりません。
私は、大体上記のようにやってます。
ちなみに、値ではなくて、タグの属性を取る方法も、ついでなので紹介しておきます。
例えば、上と同じような感じで、今度は、nameタグのid属性の一覧を取る、という事にしましょう。
「nameタグのid属性」とは、以下のyyyの部分です。
<name id=yyy >xxx</name>
forループ、if文は同じですので、if文の中身だけ抜粋します。
以下のようにします。
a[counter] = xmlPullParser.getAttributeValue(null,”name”);
属性取得の場合は、上記のようにgetAttributeValue()を使います。
第一引数はnull、第二引数に属性名である「name」を指定しています。
APIドキュメントによると、第一引数は「名前空間」、第二引数は「属性名」となっています。
名前空間が不活性ならば、第一引数はnullでないといけない、と書いてますので、今回はnullにしています。
「XML名前空間」について、私は詳しくありませんので、ここではその説明はしません。
いや、できません。(苦笑)
getAttributeValue()は、もう一つの使い方として、int型の引数を一つ持つパターンも用意されています。
これは、インデックスを指定するようですので、もし今回のケースを置き換えるならば、一つ目の属性なので、
a[counter] = xmlPullParser.getAttributeValue(0);
となります。
配列の添字と同じく、実際の番号から1を引いた値を指定します。
上記で紹介した方法だけでも使えれば、WebサービスAPIで取得したXMLの解析なら行えます。