服務端返回 String 類型數據,但內容符合 XML 格式。Android 客戶端需將其解析為對象或數據結構。
| 方案 | 優點 | 缺點 | 適用場景 |
|---|---|---|---|
| XmlPullParser(Android 官方推薦) | 輕量、流式、低內存、性能高、無第三方依賴 | 代碼較繁瑣,需手寫狀態機 | 大多數 Android 項目,特別是關注性能、包體積 |
DOM Parser(DocumentBuilderFactory) |
樹狀結構,隨機訪問,代碼直觀 | 需將整個文檔載入內存,大文件易 OOM | 小型配置文件、離線文檔 |
| SAX Parser | 流式、低內存、事件驅動 | 只能順序讀取,無法回溯,代碼較複雜 | 大文件、流式處理 |
| 第三方庫:Simple XML / JAXB / FastXML | 註解驅動,自動映射對象,開發效率極高 | 增加依賴體積,部分庫需適配 Android(如 JAXB 需 MultiDex) | 複雜對象映射、團隊熟悉註解風格 |
| 轉 JSON 再用 Gson/Moshi | 統一數據層邏輯,利用成熟 JSON 庫 | 需額外轉換步驟,可能丟失 XML 命名空間等信息 | 已有完善 JSON 基礎設施、後端可協調改 JSON |
public List<Item> parseXml(String xmlString) throws XmlPullParserException, IOException {
XmlPullParser parser = Xml.newPullParser();
parser.setInput(new StringReader(xmlString));
List<Item> items = new ArrayList<>();
Item current = null;
int eventType = parser.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
String tag = parser.getName();
switch (eventType) {
case XmlPullParser.START_TAG:
if ("item".equals(tag)) {
current = new Item();
current.id = parser.getAttributeValue(null, "id");
} else if (current != null) {
if ("title".equals(tag)) current.title = parser.nextText();
else if ("desc".equals(tag)) current.desc = parser.nextText();
}
break;
case XmlPullParser.END_TAG:
if ("item".equals(tag) && current != null) {
items.add(current);
current = null;
}
break;
}
eventType = parser.next();
}
return items;
}
data class (Kotlin) 或 @Data (Lombok) 承載解析結果;Schedulers.io() / Coroutines Dispatchers.IO);XmlPullParserException、IOException,返回空列表或拋業務異常;