บทนำ
ตัวอย่างนี้แสดงวิธีแยกวิเคราะห์ (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_WHITESPACE | Whitespace ที่ไม่สำคัญ |
COMMENT | พบ Comment <!-- --> |
DOCDECL | DOCTYPE declaration |
PROCESSING_INSTRUCTION | Processing instruction |
เปรียบเทียบ XML Parsers ใน Android
| Parser | ประเภท | หน่วยความจำ | ความเร็ว | ความยาก |
|---|---|---|---|---|
| XMLPullParser | Pull (Event-driven) | ต่ำมาก | เร็ว | ปานกลาง |
| SAX | Push (Callback) | ต่ำ | เร็ว | ปานกลาง |
| DOM | Tree-based | สูง (โหลดทั้งไฟล์) | ช้ากว่า | ง่าย |
แนวทางทันสมัย: kotlinx-serialization / SimpleXml
สำหรับโปรเจกต์ใหม่ ควรพิจารณา Library ที่รองรับ Kotlin Serialization หรือ SimpleXmlFramework เพื่อลด Boilerplate code