SAX解析是XML解析的常用方式之一,基于事件驱动模式运行,解析过程中会触发对应节点的事件,开发者可以通过自定义处理器来捕获这些事件,提取节点中的数据并完成对象封装。这种方式不需要一次性把整个XML文档加载到内存中,适合处理数据量较大的XML文件。

SAX解析封装对象的核心思路
要实现XML到对象的封装,核心步骤分为三步:首先定义和XML结构对应的Java实体类,明确每个节点要映射的属性;然后自定义SAX解析的处理器,重写事件回调方法,在对应节点触发时记录数据;最后在解析过程中把收集到的数据组装成实体类对象。
准备实体类和XML文档
先定义一个简单的用户实体类,对应XML中的用户信息节点:
public class User {
private String id;
private String name;
private Integer age;
// 省略getter、setter和toString方法
}再准备一个待解析的XML文档,内容如下:
<users>
<user id="1001">
<name>张三</name>
<age>25</age>
</user>
<user id="1002">
<name>李四</name>
<age>28</age>
</user>
</users>自定义SAX解析处理器
自定义处理器需要继承org.xml.sax.helpers.DefaultHandler,重写对应的事件方法,完成数据收集:
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 UserSAXHandler extends DefaultHandler {
// 存储最终解析出的用户对象集合
private List<User> userList = new ArrayList<>();
// 当前正在处理的用户对象
private User currentUser;
// 记录当前解析到的节点名称
private String currentTag;
public List<User> getUserList() {
return userList;
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
currentTag = qName;
// 遇到user节点时,创建新的User对象,同时读取id属性
if ("user".equals(qName)) {
currentUser = new User();
String id = attributes.getValue("id");
currentUser.setId(id);
}
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
// 只处理name和age节点的文本内容
if (currentUser != null) {
String value = new String(ch, start, length).trim();
if (!value.isEmpty()) {
if ("name".equals(currentTag)) {
currentUser.setName(value);
} else if ("age".equals(currentTag)) {
currentUser.setAge(Integer.parseInt(value));
}
}
}
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
// user节点结束时,把当前对象加入集合
if ("user".equals(qName)) {
userList.add(currentUser);
currentUser = null;
}
currentTag = null;
}
}执行SAX解析完成对象封装
编写解析入口方法,调用SAX解析器执行解析:
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.File;
import java.util.List;
public class SAXParseDemo {
public static void main(String[] args) {
try {
// 创建SAX解析器工厂
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser parser = factory.newSAXParser();
// 创建自定义处理器
UserSAXHandler handler = new UserSAXHandler();
// 执行解析,传入XML文件和处理器
parser.parse(new File("user.xml"), handler);
// 获取解析后的对象集合
List<User> userList = handler.getUserList();
// 输出结果验证
for (User user : userList) {
System.out.println(user);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}注意事项
- 解析过程中
characters方法可能会被多次调用,需要做好空值判断,避免读取到无用的空白字符 - XML文档的标签名称和实体类属性要提前对应好,避免节点名称匹配错误导致数据丢失
- 如果XML中有特殊字符或者命名空间,需要在处理器中做对应的兼容处理
- 大体积XML解析时,不要在处理器中做过多的额外业务逻辑,避免影响解析效率
SAX解析XML封装对象Java_XMLSAX_handlerDocument_parse修改时间:2026-06-03 14:56:02