Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Android

วิธี Parse XML ด้วย XMLPullParser ใน Android Kotlin

บทนำ

ตัวอย่างนี้แสดงวิธีแยกวิเคราะห์ (Parse) ไฟล์ XML โดยใช้ XMLPullParser ซึ่งเป็น Parser แบบ Pull (Event-driven) ที่มีประสิทธิภาพและใช้หน่วยความจำน้อย

ขั้นตอนที่ 1: สร้างโปรเจกต์

สร้างโปรเจกต์ Android ใหม่ใน Android Studio

ขั้นตอนที่ 2: Layout หลัก (activity_main.xml)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <ListView
        android:id="@+id/listView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:dividerHeight="1dp" />
</LinearLayout>

ขั้นตอนที่ 3: Layout รายการ (res/layout/item_row.xml)

<?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="wrap_content"
    android:padding="16dp">

    <TextView
        android:id="@+id/tvName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="@android:color/black"
        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="4dp"
        android:textColor="#666"
        android:textSize="14sp" />

    <TextView
        android:id="@+id/tvLocation"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBaseline="@id/tvDesignation"
        android:layout_alignParentEnd="true"
        android:textColor="@android:color/black"
        android:textSize="14sp"
        android:textStyle="bold" />
</RelativeLayout>

ขั้นตอนที่ 4: ไฟล์ XML Data (assets/data.xml)

สร้างโฟลเดอร์ assets (New → Folder → Assets Folder) แล้วสร้างไฟล์ data.xml:

<?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>

ขั้นตอนที่ 5: MainActivity.kt

import android.os.Bundle
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
import java.util.*

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        title = "XML Pull Parser Demo"

        try {
            val userList = ArrayList>()
            val lv: ListView = findViewById(R.id.listView)
            
            val inputStream = assets.open("data.xml")
            val parserFactory: XmlPullParserFactory = XmlPullParserFactory.newInstance()
            val parser: XmlPullParser = parserFactory.newPullParser()
            parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false)
            parser.setInput(inputStream, null)

            var currentUser: HashMap? = null
            var currentTag = ""
            var textContent = ""
            var eventType = parser.eventType

            while (eventType != XmlPullParser.END_DOCUMENT) {
                currentTag = parser.name ?: ""
                
                when (eventType) {
                    XmlPullParser.START_TAG -> {
                        if (currentTag == "user") {
                            currentUser = HashMap()
                        }
                    }
                    XmlPullParser.TEXT -> {
                        textContent = parser.text
                    }
                    XmlPullParser.END_TAG -> {
                        when (currentTag) {
                            "name" -> currentUser?.put("name", textContent)
                            "designation" -> currentUser?.put("designation", textContent)
                            "location" -> currentUser?.put("location", textContent)
                            "user" -> currentUser?.let { userList.add(it) }
                        }
                    }
                }
                eventType = parser.next()
            }

            val adapter = SimpleAdapter(
                this,
                userList,
                R.layout.item_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: Manifest

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
    package="com.example.xmlparser">
    <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>

XMLPullParser Event Types

Constantคำอธิบาย
START_DOCUMENTเริ่มต้นเอกสาร
END_DOCUMENTจบเอกสาร
START_TAGพบแท็กเปิด <tag>
END_TAGพบแท็กปิด </tag>
TEXTพบข้อความภายในแท็ก
CDSECTพบ CDATA section
ENTITY_REFพบ Entity reference
IGNORABLE_WHITESPACEWhitespace ที่ไม่สำคัญ
COMMENTพบ Comment <!-- -->
DOCDECLDOCTYPE declaration
PROCESSING_INSTRUCTIONProcessing instruction

เปรียบเทียบ XML Parsers ใน Android

Parserประเภทหน่วยความจำความเร็วความยาก
XMLPullParserPull (Event-driven)ต่ำมากเร็วปานกลาง
SAXPush (Callback)ต่ำเร็วปานกลาง
DOMTree-basedสูง (โหลดทั้งไฟล์)ช้ากว่าง่าย

แนวทางทันสมัย: kotlinx-serialization / SimpleXml

สำหรับโปรเจกต์ใหม่ ควรพิจารณา Library ที่รองรับ Kotlin Serialization หรือ SimpleXmlFramework เพื่อลด Boilerplate code