Java中的SAX解析是一种基于事件驱动的XML解析方式,相比DOM解析更节省内存,适合处理大体积XML文件。SAXParserFactory作为SAX解析器的工厂类,负责创建SAXParser实例,是使用SAX解析XML的入口类。

SAXParserFactory基础使用流程
使用SAXParserFactory解析XML的核心步骤可以分为四步,下面逐步说明每个步骤的作用和实现方式。
1. 获取SAXParserFactory实例
SAXParserFactory是一个抽象类,不能直接实例化,需要通过它的静态方法newInstance()获取工厂实例,该方法会自动查找系统可用的SAX解析器实现。
import javax.xml.parsers.SAXParserFactory;
import javax.xml.parsers.SAXParser;
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.SAXException;
import java.io.IOException;
public class SAXDemo {
public static void main(String[] args) {
// 获取SAXParserFactory实例
SAXParserFactory factory = SAXParserFactory.newInstance();
}
}
2. 配置工厂参数
获取工厂实例后,可以根据需求配置相关参数,常用的配置项包括是否开启命名空间支持、是否验证XML等。
- setNamespaceAware(boolean awareness):设置是否支持XML命名空间,默认值为false,如果XML包含命名空间建议设置为true
- setValidating(boolean validating):设置是否开启XML验证,默认值为false,开启后会根据DTD或者Schema验证XML格式合法性
- setFeature(String name, boolean value):设置更细粒度的解析特性,比如关闭外部实体加载避免XXE漏洞
下面是配置工厂的示例代码:
public class SAXDemo {
public static void main(String[] args) throws Exception {
SAXParserFactory factory = SAXParserFactory.newInstance();
// 开启命名空间支持
factory.setNamespaceAware(true);
// 关闭XML验证
factory.setValidating(false);
// 关闭外部通用实体加载,避免XXE攻击
factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
// 关闭外部参数实体加载
factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
}
}
3. 创建SAXParser实例
配置完工厂参数后,调用工厂的newSAXParser()方法就可以创建SAXParser解析器实例,该方法可能会抛出解析器配置异常或者解析器实现不存在的异常。
public class SAXDemo {
public static void main(String[] args) throws Exception {
SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setNamespaceAware(true);
// 创建SAXParser实例
SAXParser parser = factory.newSAXParser();
}
}
4. 创建解析处理器并执行解析
SAX解析是基于事件触发的,需要自定义一个继承DefaultHandler的处理器类,重写对应的事件方法,比如startElement、endElement、characters等,然后调用SAXParser的parse方法执行解析。
首先定义处理器类:
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import java.lang.StringBuilder;
// 自定义SAX解析处理器
class MySAXHandler extends DefaultHandler {
// 用于存储当前解析的文本内容
private StringBuilder content = new StringBuilder();
// 遇到元素开始标签时触发
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
System.out.println("遇到开始标签:" + qName);
// 如果有属性,打印属性信息
if (attributes.getLength() > 0) {
for (int i = 0; i < attributes.getLength(); i++) {
System.out.println("属性名:" + attributes.getQName(i) + ",属性值:" + attributes.getValue(i));
}
}
// 重置文本内容缓存
content.setLength(0);
}
// 遇到元素结束标签时触发
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
System.out.println("遇到结束标签:" + qName + ",文本内容:" + content.toString().trim());
}
// 解析元素文本内容时触发
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
content.append(ch, start, length);
}
}
然后执行完整的解析流程:
import javax.xml.parsers.SAXParserFactory;
import javax.xml.parsers.SAXParser;
import java.io.File;
public class SAXDemo {
public static void main(String[] args) throws Exception {
// 1. 获取工厂实例
SAXParserFactory factory = SAXParserFactory.newInstance();
// 2. 配置工厂参数
factory.setNamespaceAware(true);
factory.setValidating(false);
// 3. 创建解析器实例
SAXParser parser = factory.newSAXParser();
// 4. 创建处理器并执行解析,这里解析当前目录下的test.xml文件
MySAXHandler handler = new MySAXHandler();
parser.parse(new File("test.xml"), handler);
}
}
常见问题说明
- 如果调用
newInstance()时抛出FactoryConfigurationError,说明系统没有找到可用的SAX解析器实现,需要检查是否引入了相关依赖,比如Java自带的JAXP实现或者第三方Xerces实现 - 解析外部XML文件时如果开启外部实体加载,可能会导致XXE漏洞,生产环境建议关闭相关外部实体特性
- SAX解析是顺序读取XML的,解析过程中不能像DOM那样随机访问节点,只能按照事件顺序处理
注意:如果需要解析的XML文件来自不可信的来源,一定要做好安全配置,避免解析过程中的安全风险。
总结
SAXParserFactory的使用核心就是先获取工厂实例,按需配置工厂参数,再通过工厂创建SAXParser,最后结合自定义处理器完成XML解析。整个过程不需要加载整个XML到内存,适合处理大文件,开发者只需要关注自己需要处理的解析事件即可,上手难度不高,是Java中处理XML的常用方式之一。
SAXParserFactorySAX解析器Java_XML解析XML_parser工厂方法修改时间:2026-06-19 12:06:35