Android如何使用DOM和SAXParserFactory来解析XML文件

来源:苹果APP网作者:石川澪头衔:网络博主
导读:本期聚焦于小伙伴创作的《Android如何使用DOM和SAXParserFactory来解析XML文件》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《Android如何使用DOM和SAXParserFactory来解析XML文件》有用,将其分享出去将是对创作者最好的鼓励。

在Android应用开发中,经常会遇到需要解析XML格式数据的场景,比如解析服务端的配置信息、接口返回的XML格式数据等。DOM和基于SAXParserFactory的SAX解析是两种常用的XML解析方案,两者的实现逻辑和适用场景有明显差异,掌握它们的使用方法能更高效地完成XML解析工作。

Android如何使用DOM和SAXParserFactory来解析XML文件

DOM解析XML的使用方法

DOM解析的核心思路是先将整个XML文档加载到内存中,构建出一棵节点树,然后通过遍历节点树获取需要的数据。这种方式可以随机访问任意节点,操作灵活,但内存占用相对较高,不适合解析过大的XML文件。

DOM解析的实现步骤

  • 获取XML文件的输入流,可以是本地assets目录下的文件,也可以是网络请求返回的输入流
  • 创建DocumentBuilderFactory实例,再通过它获取DocumentBuilder实例
  • 调用DocumentBuilderparse方法解析输入流,得到Document对象
  • 通过Document对象获取根节点,再逐层遍历子节点获取数据

DOM解析代码示例

以下示例解析assets目录下的student.xml文件,文件内容如下:

<?xml version="1.0" encoding="utf-8"?>
<students>
    <student id="1">
        <name>张三</name>
        <age>20</age>
        <major>计算机科学</major>
    </student>
    <student id="2">
        <name>李四</name>
        <age>21</age>
        <major>软件工程</major>
    </student>
</students>

对应的解析代码:

import android.content.res.AssetManager;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.InputStream;

public class DomXmlParser {
    public void parseXml(AssetManager assetManager) {
        try {
            // 获取XML文件输入流
            InputStream is = assetManager.open("student.xml");
            // 创建DocumentBuilderFactory实例
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            // 获取DocumentBuilder实例
            DocumentBuilder builder = factory.newDocumentBuilder();
            // 解析输入流得到Document对象
            Document document = builder.parse(is);
            // 获取根节点students
            Element rootElement = document.getDocumentElement();
            // 获取所有student节点
            NodeList studentNodes = rootElement.getElementsByTagName("student");
            for (int i = 0; i < studentNodes.getLength(); i++) {
                Node studentNode = studentNodes.item(i);
                if (studentNode.getNodeType() == Node.ELEMENT_NODE) {
                    Element studentElement = (Element) studentNode;
                    // 获取student节点的id属性
                    String id = studentElement.getAttribute("id");
                    // 获取name子节点内容
                    String name = studentElement.getElementsByTagName("name").item(0).getTextContent();
                    // 获取age子节点内容
                    String age = studentElement.getElementsByTagName("age").item(0).getTextContent();
                    // 获取major子节点内容
                    String major = studentElement.getElementsByTagName("major").item(0).getTextContent();
                    // 打印解析结果
                    System.out.println("学生ID:" + id + ",姓名:" + name + ",年龄:" + age + ",专业:" + major);
                }
            }
            is.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

使用SAXParserFactory实现SAX解析

SAX解析是基于事件驱动的模式,解析时会逐行读取XML内容,遇到不同的节点(如开始标签、结束标签、文本内容)时触发对应的回调方法,不需要将整个文档加载到内存,内存占用低,适合解析大体积XML文件,但无法随机访问节点,只能顺序解析。

SAX解析的实现步骤

  • 创建SAXParserFactory实例,通过它获取SAXParser实例
  • 自定义DefaultHandler的子类,重写事件回调方法,在回调中处理解析到的数据
  • 调用SAXParserparse方法,传入XML输入流和自定义的Handler实例

SAXParserFactory解析代码示例

同样解析上面的student.xml文件,自定义Handler类:

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import java.util.ArrayList;
import java.util.List;

public class StudentHandler extends DefaultHandler {
    private List<Student> studentList;
    private Student currentStudent;
    private String currentTagName;

    public List<Student> getStudentList() {
        return studentList;
    }

    @Override
    public void startDocument() throws SAXException {
        super.startDocument();
        studentList = new ArrayList<>();
    }

    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        super.startElement(uri, localName, qName, attributes);
        currentTagName = qName;
        if ("student".equals(qName)) {
            currentStudent = new Student();
            // 获取id属性
            String id = attributes.getValue("id");
            currentStudent.setId(id);
        }
    }

    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        super.characters(ch, start, length);
        if (currentStudent != null && currentTagName != null) {
            String content = new String(ch, start, length).trim();
            if ("name".equals(currentTagName)) {
                currentStudent.setName(content);
            } else if ("age".equals(currentTagName)) {
                currentStudent.setAge(content);
            } else if ("major".equals(currentTagName)) {
                currentStudent.setMajor(content);
            }
        }
    }

    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        super.endElement(uri, localName, qName);
        if ("student".equals(qName)) {
            studentList.add(currentStudent);
            currentStudent = null;
        }
        currentTagName = null;
    }

    @Override
    public void endDocument() throws SAXException {
        super.endDocument();
    }
}

// 学生实体类
class Student {
    private String id;
    private String name;
    private String age;
    private String major;

    // 省略getter和setter方法
    public String getId() { return id; }
    public void setId(String id) { this.id = id; }
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public String getAge() { return age; }
    public void setAge(String age) { this.age = age; }
    public String getMajor() { return major; }
    public void setMajor(String major) { this.major = major; }
}

调用解析的代码:

import android.content.res.AssetManager;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.InputStream;

public class SaxXmlParser {
    public void parseXml(AssetManager assetManager) {
        try {
            // 获取XML文件输入流
            InputStream is = assetManager.open("student.xml");
            // 创建SAXParserFactory实例
            SAXParserFactory factory = SAXParserFactory.newInstance();
            // 获取SAXParser实例
            SAXParser parser = factory.newSAXParser();
            // 创建自定义Handler
            StudentHandler handler = new StudentHandler();
            // 开始解析
            parser.parse(is, handler);
            // 获取解析结果
            for (Student student : handler.getStudentList()) {
                System.out.println("学生ID:" + student.getId() + ",姓名:" + student.getName() + ",年龄:" + student.getAge() + ",专业:" + student.getMajor());
            }
            is.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

两种解析方式的对比与选择

开发者可以根据实际场景选择合适的解析方式:

对比项DOM解析SAX解析(SAXParserFactory)
内存占用较高,需要加载整个文档到内存较低,逐行读取,不需要全量加载
访问方式支持随机访问任意节点只能顺序访问,无法回退
适用场景XML文档较小,需要频繁操作节点数据XML文档较大,只需要顺序读取数据
实现复杂度逻辑简单,代码直观需要自定义Handler,逻辑稍复杂

注意事项

  • 解析网络XML时需要在子线程中执行,避免阻塞主线程,同时需要申请网络权限
  • 解析完成后及时关闭输入流,避免资源泄漏
  • 如果遇到XML格式不规范的情况,两种解析方式都可能抛出异常,需要做好异常处理
  • 如果XML文件过大,优先选择SAX解析,避免内存溢出

DOM解析SAXParserFactoryXML解析Android修改时间:2026-06-06 14:32:29

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。