XML 在 Android 開發中廣泛用於資料交換、配置檔案、網路回應等場景。本文將系統介紹 Android 中主流的 XML 解析方式,並針對實際開發需求提供最佳實踐建議。
| 解析器 | 特點 | 適用場景 |
|---|---|---|
| DOM (Document Object Model) | 將整個 XML 載入記憶體形成樹狀結構,操作直觀但記憶體佔用大 | 小型 XML 檔案、需隨機存取節點、配置檔解析 |
| SAX (Simple API for XML) | 事件驅動、流式讀取、不佔用大量記憶體、只能順序讀取 | 大型 XML 檔案、記憶體受限環境、單次順序解析 |
| XmlPullParser (Android 推薦) | 類似 SAX 但可控制解析流程、效能最佳、記憶體效率高、Kotlin/Java 皆友善 | 大多數 Android 應用場景、網路資料解析、高效能需求 |
針對您提供的 XML 結構:
<xmldump>
<mfs id="3" name="str1" path="/mnt/sdcard/path2" type="2" desc="des3)" />
<mfs id="1" name="st2" path="/mnt/sdcard/path1" type="2" desc="des2" />
<mfs id="2" name="stvr3" path="/mnt/sdcard/path3" type="2" desc="des1" />
</xmldump>
以下是完整解析程式碼,將資料映射為資料類別:
data class MfsItem(
val id: String,
val name: String,
val path: String,
val type: String,
val desc: String
)
fun parseMfsXml(inputStream: InputStream): List {
val items = mutableListOf()
val parser = Xml.newPullParser()
parser.setInput(inputStream, "UTF-8")
var eventType = parser.eventType
var currentItem: MfsItem? = null
while (eventType != XmlPullParser.END_DOCUMENT) {
when (eventType) {
XmlPullParser.START_TAG -> {
if (parser.name == "mfs") {
currentItem = MfsItem(
id = parser.getAttributeValue(null, "id") ?: "",
name = parser.getAttributeValue(null, "name") ?: "",
path = parser.getAttributeValue(null, "path") ?: "",
type = parser.getAttributeValue(null, "type") ?: "",
desc = parser.getAttributeValue(null, "desc") ?: ""
)
}
}
XmlPullParser.END_TAG -> {
if (parser.name == "mfs" && currentItem != null) {
items.add(currentItem)
currentItem = null
}
}
}
eventType = parser.next()
}
return items
}
若 XML 結構較簡單且檔案較小,DOM 寫法更直觀:
fun parseWithDom(inputStream: InputStream): List {
val items = mutableListOf()
val builder = DocumentBuilderFactory.newInstance().newDocumentBuilder()
val doc = builder.parse(inputStream)
doc.documentElement.normalize()
val nodeList = doc.getElementsByTagName("mfs")
for (i in 0 until nodeList.length) {
val element = nodeList.item(i) as Element
items.add(MfsItem(
id = element.getAttribute("id"),
name = element.getAttribute("name"),
path = element.getAttribute("path"),
type = element.getAttribute("type"),
desc = element.getAttribute("desc")
))
}
return items
}
res/xml/ 下檔案)。始終明確指定編碼:parser.setInput(inputStream, "UTF-8") 或根據來源指定正確編碼(如 GB2312)。
若 XML 含命名空間,需使用 parser.getAttributeValue(namespace, name),或設定 parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true)。
大型 XML 必須在背景執行緒(如 Coroutines、RxJava、AsyncTask)解析,避免阻塞 UI。
XML 中的 &、<、> 等實體會自動轉義,但 CDATA 區塊需特殊處理。
對於複雜 XML 結構,建議使用成熟庫簡化開發:
Android XML 解析首選 XmlPullParser,兼顧效能與記憶體效率。針對您的屬性型扁平結構,XmlPullParser 的 getAttributeValue 最為直接高效。記住:大檔案必須背景執行緒解析,明確指定編碼,善用資料類別映射結果,才能寫出健壯、可維護的解析代碼。