首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Java XML 解析:Pull 解析器完整實戰 (Android 內置標準)

     編輯:Java 綜合教學

什麼是 Pull 解析?

Pull 解析 (Pull Parsing) 是一種流式、基於事件的 XML 解析方式,與 SAX 類似但控制權在開發者手中:代碼主動調用 next() 推進解析器,根據當前事件類型 (START_TAG, TEXT, END_TAG...) 決定處理邏輯。
它是 Android 官方推薦、內置無需第三方庫 的解析器 (org.xmlpull.v1),輕量、高效、適合移動端及大文件流式處理。

示例 XML 數據 (students.xml)

<?xml version="1.0" encoding="UTF-8"?>
<students>
    <student name="zhangsan">
        <age>18</age>
        <sex>男</sex>
    </student>
    <student name="lisi">
        <age>22</age>
        <sex>女</sex>
    </student>
    <student name="wangwu">
        <age>20</age>
        <sex>男</sex>
    </student>
</students>

實體類

public class Student {
    private String name;
    private int age;
    private String sex;
    // 構造器、Getter/Setter、toString() 省略
}

核心解析代碼詳解

public class PullParserDemo {
    public static List<Student> parse(InputStream inputStream) throws XmlPullParserException, IOException {
        // 1. 獲取解析器工廠與實例
        XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
        // factory.setNamespaceAware(true); // 若 XML 有命名空間需開啟
        XmlPullParser parser = factory.newPullParser();

        // 2. 設置輸入源 (編碼需與 XML 聲明一致)
        parser.setInput(inputStream, "UTF-8");

        List<Student> students = null;
        Student currentStudent = null;

        // 3. 獲取初始事件類型
        int eventType = parser.getEventType();

        // 4. 循環處理直到文檔結束
        while (eventType != XmlPullParser.END_DOCUMENT) {
            switch (eventType) {
                case XmlPullParser.START_TAG:
                    String tagName = parser.getName();
                    if ("students".equals(tagName)) {
                        students = new ArrayList<>(); // 初始化列表
                    } else if ("student".equals(tagName)) {
                        currentStudent = new Student();
                        // 獲取屬性值:命名空間為 null,屬性名為 "name"
                        currentStudent.setName(parser.getAttributeValue(null, "name"));
                        students.add(currentStudent); // 早加入列表,便於後續設置屬性
                    } else if ("age".equals(tagName)) {
                        // nextText() 會推進到 TEXT 事件並返回文本內容,再推進到 END_TAG
                        currentStudent.setAge(Integer.parseInt(parser.nextText()));
                    } else if ("sex".equals(tagName)) {
                        currentStudent.setSex(parser.nextText());
                    }
                    break;

                case XmlPullParser.END_TAG:
                    // 結束標籤通常無需處理,除非需在元素結束時做特定邏輯
                    break;

                case XmlPullParser.TEXT:
                    // 純文本節點,若未用 nextText() 可在這裡用 getText()
                    // 注意:若上層已用 nextText() 消費了 TEXT 事件,這裡不會再進入
                    break;
            }
            // 關鍵:推進到下一個事件
            eventType = parser.next();
        }
        return students;
    }
}

關鍵 API 對照表

方法說明
getEventType()獲取當前事件類型 (START_DOCUMENT, START_TAG, TEXT, END_TAG, END_DOCUMENT...)
next()推進到下一個事件,返回新事件類型
nextText()便利方法:要求當前是 START_TAG,直接返回下一個 TEXT 內容,並自動推進到對應的 END_TAG。解析元素文本首選。
getName()獲取當前標籤名 (START_TAG/END_TAG 時有效)
getAttributeValue(ns, name)獲取屬性值,ns 為命名空間 URI (無則 null)
getText()獲取當前 TEXT 事件的文本內容
getDepth()獲取當前元素深度 (根元素深度 1),可用於判斷層級

Pull vs SAX vs DOM 選型指南

維度DOMSAXPull (XmlPullParser)
記憶體佔用高 (整棵樹加載內存)極低 (流式)極低 (流式)
解析控制權樹結構隨意遍歷解析器推送事件 (回調)開發者拉取事件 (主動)
代碼複雜度低 (樹操作直觀)中 (狀態機管理)中低 (流程清晰,邏輯集中)
修改 XML易 (內存樹修改後寫回)難 (只讀)難 (只讀)
Android 推薦度小文件可用不推薦 (需引包)首選 (系統內置)
適用場景配置文件、小數據、需隨機訪問/修改大文件、只讀、內存受限、舊項目大文件、只讀、Android、Kotlin/Java 通用、需精確控制流程

常見坑與最佳實踐

  1. 編碼一致性: parser.setInput(stream, "UTF-8") 必須與 XML 頭聲明一致,否則中文亂碼。
  2. 命名空間: XML 若有 xmlns="...",需 factory.setNamespaceAware(true),且 getName() 返回帶前綴名,getAttributeValue(ns, name) 需傳入真實命名空間 URI。
  3. nextText() 前置條件:當前事件必須是 START_TAG,且元素必須包含文本內容 (空元素會拋異常),調用後指針移至 END_TAG。
  4. 異常處理: 捕獲 XmlPullParserException (格式錯誤) 和 IOException (IO錯誤)。
  5. 資源關閉: 使用 try-with-resources 管理 InputStream。

總結: Pull 解析以「主動拉取、流式處理、代碼邏輯集中」著稱,是 Android 及 Java 輕量級 XML 解析的首選。掌握 START_TAG 判斷分發 + nextText() 取值 + next() 推進 這套核心節奏即可應對大多數場景。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved