Android
 Computer >> コンピューター >  >> プログラミング >> Android

KotlinのXmlPullParserでAndroidアプリのXMLを解析する方法【サンプルコード付き】

XmlPullParserとは?

XmlPullParserは、Androidに標準で組み込まれている軽量なXMLパーサーです。ドキュメントを先頭から順に読み進めながら、開始タグ・テキスト・終了タグといったイベントを1つずつ受け取る「プル型(イベント駆動)」方式のため、メモリ消費が少なく、大きなXMLファイルの解析にも適しています。

この記事では、Kotlinを使ってassetsフォルダに配置したXMLファイルをXmlPullParserで解析し、その結果をListViewに一覧表示するサンプルアプリを段階的に作成していきます。

手順1:新規プロジェクトを作成する

Android Studioを起動し、メニューから「File」→「New Project」を選択します。必要な項目をすべて入力して、新しいプロジェクトを作成しましょう。

手順2:メインレイアウト(activity_main.xml)を編集する

res/layout/activity_main.xml に以下のコードを追加します。解析結果の一覧を表示するためのListViewを、縦方向のLinearLayoutの中に配置しています。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical">
    <ListView
        android:id="@+id/listView"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:dividerHeight="1dp" />
</LinearLayout>

手順3:行レイアウト(row.xml)を作成する

続いて、ListViewの各行のデザインを定義するレイアウトリソースファイル「row.xml」を作成し、以下のコードを記述します。名前(tvName)、役職(tvDesignation)、所在地(tvLocation)の3つのTextViewを配置しています。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="4dp">
    <TextView
        android:id="@+id/tvName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="@android:color/background_dark"
        android:textSize="16sp"
        android:textStyle="bold" />
    <TextView
        android:id="@+id/tvDesignation"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/tvName"
        android:layout_marginTop="7dp"
        android:textColor="#343434"
        android:textSize="12sp" />
    <TextView
        android:id="@+id/tvLocation"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBaseline="@+id/tvDesignation"
        android:layout_alignBottom="@+id/tvDesignation"
        android:layout_alignParentEnd="true"
        android:textColor="@android:color/background_dark"
        android:textSize="16sp" />
</RelativeLayout>

手順4:assetsフォルダにXMLファイルを作成する

プロジェクトに新しいassetsフォルダを作成し、その中に「model.xml」というファイルを追加して、以下のXMLデータを記述します。ここでは3人のユーザー情報(名前・役職・所在地)を定義しています。

<?xml version="1.0" encoding="utf-8"?>
<resources>
<users>
    <user>
        <name>Sehwag</name>
        <designation>Vice Captain</designation>
        <location>Delhi</location>
    </user>
    <user>
        <name>Ashwin</name>
        <designation>Off Spin Bowler</designation>
        <location>Chennai</location>
    </user>
    <user>
        <name>Dhoni</name>
        <designation>Captain</designation>
        <location>Ranchi</location>
    </user>
</users>
</resources>

※ パーサー側で「location」タグを判定するため、XML側のタグ名も「location」に統一しておきましょう。タグ名が一致しないと値が正しく取得できません。

手順5:MainActivity.ktにパース処理を実装する

src/MainActivity.kt に以下のコードを追加します。処理の流れは次のとおりです。

  • XmlPullParserFactoryからパーサーのインスタンスを生成する
  • assetsフォルダのmodel.xmlを入力ストリームとしてパーサーにセットする
  • eventTypeを判定しながら、ドキュメントの終端までループ処理を行う
  • START_TAGで「user」タグを検出したら、新しいHashMapを生成する
  • END_TAGで「name」「designation」「location」のテキストをHashMapに格納する
  • 「user」タグの終了時にリストへ追加し、最後にSimpleAdapter経由でListViewに表示する
import android.os.Bundle
import android.widget.ListAdapter
import android.widget.ListView
import android.widget.SimpleAdapter
import androidx.appcompat.app.AppCompatActivity
import org.xmlpull.v1.XmlPullParser
import org.xmlpull.v1.XmlPullParserException
import org.xmlpull.v1.XmlPullParserFactory
import java.io.IOException

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        title = "KotlinApp"
        try {
            val userList = ArrayList<java.util.HashMap<String?, String?>>()
            var user: HashMap<String?, String?>? = HashMap()
            val lv: ListView = findViewById(R.id.listView)
            val inputStream = assets.open("model.xml")
            val parserFactory: XmlPullParserFactory = XmlPullParserFactory.newInstance()
            val parser: XmlPullParser = parserFactory.newPullParser()
            parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true)
            parser.setInput(inputStream, null)
            var tag: String?
            var text = ""
            var event = parser.eventType
            while (event != XmlPullParser.END_DOCUMENT) {
                tag = parser.name
                when (event) {
                    XmlPullParser.START_TAG -> if (tag == "user") user = HashMap()
                    XmlPullParser.TEXT -> text = parser.text
                    XmlPullParser.END_TAG -> when (tag) {
                        "name" -> user!!["name"] = text
                        "designation" -> user!!["designation"] = text
                        "location" -> user!!["location"] = text
                        "user" -> if (user != null) userList.add(user)
                    }
                }
                event = parser.next()
            }
            val adapter: ListAdapter = SimpleAdapter(this@MainActivity, userList, R.layout.row,
                arrayOf("name", "designation", "location"), intArrayOf(R.id.tvName,
                R.id.tvDesignation, R.id.tvLocation))
            lv.adapter = adapter
        } catch (e: IOException) {
            e.printStackTrace()
        } catch (e: XmlPullParserException) {
            e.printStackTrace()
        }
    }
}

手順6:AndroidManifest.xmlを確認する

androidManifest.xml は以下のように記述します。ローカルのassetsファイルを読み込むだけなので、特別なパーミッションの宣言は不要です。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android" package="com.example.q11">
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

アプリを実行してみよう

それでは、アプリを実行してみましょう。ここでは実機のAndroidスマートフォンをPCに接続しているものとします。Android Studioでプロジェクト内のアクティビティファイルを開き、ツールバーのRunアイコンKotlinのXmlPullParserでAndroidアプリのXMLを解析する方法【サンプルコード付き】をクリックしてください。デバイスの選択画面が表示されたら、接続したモバイルデバイスを選択します。

アプリが起動すると、端末の画面にXMLから解析したユーザー情報(名前・役職・所在地)の一覧がListViewとして表示されます。

KotlinのXmlPullParserでAndroidアプリのXMLを解析する方法【サンプルコード付き】

まとめ

このように、XmlPullParserを使えばイベント駆動方式でシンプルかつ省メモリにXMLを解析できます。現在はJSONがデータ交換の主流ですが、RSSフィードやレガシーAPI、設定ファイルなど、XML形式のデータを扱う場面は依然として多くあります。基本的な流れ(パーサーの生成→入力ソースの設定→イベントループでの解析)を押さえておけば、さまざまなXMLデータに応用できるので、ぜひマスターしておきましょう。

  1. 【Android】XmlPullParserを使ってXMLを解析する方法をステップ別に解説

    XmlPullParserとは XmlPullParserは、Androidに標準で組み込まれているXMLパーサーです。イベント駆動型(プル型)の解析方式を採用しており、XMLドキュメントを先頭から順に読み進めながら「開始タグ」「テキスト」「終了タグ」といったイベントを一つずつ処理していきます。DOMのようにドキュメント全体をメモリ上に展開しないため、省メモリかつ高速に動作し、リソースが限られたモバイル環境でのXML解析に最適です。 本記事では、XmlPullParserを使ってユーザー情報が記述されたXMLファイルを解析し、その結果をListViewに表示するサンプルアプリの作成手順を、ステ

  2. 【Android開発】Volleyライブラリを使ってJSONを解析する方法をステップ解説

    Volleyライブラリとは この記事では、AndroidアプリでVolleyライブラリを使用してJSONデータを解析(パース)する方法を、ステップごとにわかりやすく解説します。VolleyはGoogleが提供するHTTP通信ライブラリで、ネットワークリクエストの管理やJSONの取得・解析を少ないコード量で実現できるのが特徴です。 ステップ1:新規プロジェクトの作成 まず、Android Studioで新しいプロジェクトを作成します。メニューから「File」→「New Project」を選択し、必要な項目をすべて入力してプロジェクトを生成してください。 ステップ2:レイアウトファイル(act