Python的xml.sax.handler模块提供了SAX解析XML时的处理器基类,开发者可以通过继承这些基类并重写对应方法,实现自定义的XML内容处理逻辑,适配不同的业务场景需求。

xml.sax.handler核心基类介绍
xml.sax.handler模块中常用的基类有两个,分别是ContentHandler和DTDHandler,其中ContentHandler是处理XML内容最常用的基类,几乎所有的内容处理逻辑都基于它实现。
ContentHandler提供了一系列回调方法,当SAX解析器读取XML文件时,遇到不同的XML结构就会自动调用对应的方法,开发者只需要重写这些方法就能实现自定义逻辑。
常用回调方法说明
- startDocument():解析器开始处理XML文档时调用,一般用于初始化资源
- endDocument():解析器处理完整个XML文档时调用,一般用于释放资源或收尾操作
- startElement(name, attrs):遇到XML开始标签时调用,name是标签名,attrs是标签的属性集合
- endElement(name):遇到XML结束标签时调用,name是标签名
- characters(content):遇到XML标签内的文本内容时调用,content就是文本内容
自定义SAX处理器实现步骤
自定义SAX处理器的整体流程可以分为三步:继承ContentHandler基类、重写需要的回调方法、将自定义处理器注册到SAX解析器中执行。
第一步:继承ContentHandler基类
首先创建自定义的处理器类,继承xml.sax.handler.ContentHandler,然后根据需求定义类内部的属性,用于存储解析过程中需要暂存的数据。
第二步:重写回调方法
根据要处理的XML结构,重写对应的回调方法。比如要提取所有标签的文本内容,就重写characters方法;要处理特定标签的属性,就重写startElement方法。
第三步:注册并执行解析
使用xml.sax.parse方法或者xml.sax.make_parser创建解析器,将自定义的处理器实例设置到解析器中,然后传入XML文件或XML字符串开始解析。
完整代码示例
下面以解析一个存储书籍信息的XML文件为例,实现自定义SAX处理器,提取所有书籍的标题和价格信息。
首先准备测试的XML内容,假设内容如下:
<?xml version="1.0" encoding="utf-8"?>
<bookstore>
<book category="编程">
<title>Python编程入门</title>
<price>59.9</price>
</book>
<book category="文学">
<title>平凡的世界</title>
<price>39.8</price>
</book>
</bookstore>
自定义SAX处理器的Python代码如下:
import xml.sax
from xml.sax.handler import ContentHandler
# 自定义SAX处理器类
class BookHandler(ContentHandler):
def __init__(self):
super().__init__()
# 当前处理的标签名
self.current_tag = None
# 存储解析到的书籍信息
self.books = []
# 临时存储单本书籍的信息
self.current_book = {}
def startElement(self, name, attrs):
# 遇到开始标签时,记录当前标签名
self.current_tag = name
# 如果是book标签,初始化当前书籍信息
if name == "book":
self.current_book = {}
# 提取category属性
if "category" in attrs:
self.current_book["category"] = attrs["category"]
def characters(self, content):
# 去除空白字符
content = content.strip()
if not content:
return
# 根据当前标签名,将内容存入临时书籍信息
if self.current_tag == "title":
self.current_book["title"] = content
elif self.current_tag == "price":
self.current_book["price"] = float(content)
def endElement(self, name):
# 遇到book结束标签时,将当前书籍信息存入列表
if name == "book":
self.books.append(self.current_book)
# 重置当前标签名
self.current_tag = None
def endDocument(self):
# 解析结束时,打印所有书籍信息
print("解析到的书籍信息:")
for book in self.books:
print(f"分类:{book.get('category')},标题:{book.get('title')},价格:{book.get('price')}")
# 创建解析器
parser = xml.sax.make_parser()
# 关闭命名空间处理
parser.setFeature(xml.sax.handler.feature_namespaces, 0)
# 设置自定义处理器
handler = BookHandler()
parser.setContentHandler(handler)
# 解析XML字符串,也可以传入文件路径解析文件
xml_content = """<?xml version="1.0" encoding="utf-8"?>
<bookstore>
<book category="编程">
<title>Python编程入门</title>
<price>59.9</price>
</book>
<book category="文学">
<title>平凡的世界</title>
<price>39.8</price>
</book>
</bookstore>"""
parser.feed(xml_content)
parser.close()
运行上述代码后,会输出解析到的所有书籍的分类、标题和价格信息,说明自定义处理器逻辑生效。
注意事项
- SAX解析是流式解析,不会将整个XML文档加载到内存中,适合处理大尺寸的XML文件,内存占用更低
characters方法可能会被多次调用,比如标签内的文本包含换行或者特殊字符时,解析器会分多次传入内容,所以需要在方法内部做内容的拼接处理- 如果需要处理XML的命名空间,需要开启解析器的命名空间特性,同时调整回调方法的参数处理逻辑
- 自定义处理器中的属性需要注意线程安全问题,如果是多线程场景下使用,需要避免共享可变状态
Pythonxml_sax_handlerSAX处理器XML解析修改时间:2026-06-30 18:09:40