Python的xml.sax模块是基于事件驱动的XML解析器,适合大文件和内存受限场景,通过继承xml.sax.ContentHandler并重写startElement、endElement、characters等方法处理标签与文本,再用xml.sax.parse()启动解析。

Python 的 xml.sax 模块是基于事件驱动的 XML 解析器,适合处理大文件、内存受限场景,不加载整个文档到内存,而是边读边触发回调。核心在于自定义一个继承 xml.sax.ContentHandler 的处理器类,并重写其中的方法来响应开始标签、结束标签、文本内容等事件。
创建自定义 ContentHandler 处理器
你需要定义一个类,继承 xml.sax.ContentHandler,并至少实现以下常用方法:
-
startElement(name, attrs):遇到起始标签时调用,
name是标签名,attrs是xml.sax.xmlreader.AttributesImpl对象,可用attrs.get('attr_name')或attrs.items()获取属性 - endElement(name):遇到结束标签时调用
- characters(content):获取标签内的文本内容(注意:可能被多次调用,内容可能被切分,需累积)
- startDocument() / endDocument():可选,分别在解析开始和结束时触发
用 xml.sax.parse() 启动解析
调用 xml.sax.parse(filename, handler) 即可开始解析。也可以用 xml.sax.parseString(xml_str, handler) 解析字符串。
示例:
立即学习“Python免费学习笔记(深入)”;
(假设有一个 books.xml 文件)Python入门 张三 数据结构 李四
对应处理器:
import xml.saxclass BookHandler(xml.sax.ContentHandler): def init(self): self.current_tag = "" self.title = "" self.author = "" self.books = []
def startElement(self, name, attrs): self.current_tag = name if name == "book": self.book_id = attrs.get("id", "") def endElement(self, name): if name == "book": self.books.append({ "id": self.book_id, "title": self.title.strip(), "author": self.author.strip() }) self.title = self.author = "" def characters(self, content): if self.current_tag == "title": self.title += content elif self.current_tag == "author": self.author += content使用
handler = BookHandler() xml.sax.parse("books.xml", handler) print(handler.books)
注意字符数据的累积与空白处理
characters()不保证一次性返回全部文本,尤其含换行或空格时,可能被拆成多次调用。务必用+=累积,并在endElement中做strip()清理首尾空白。不要在characters中直接打印或赋值,否则容易丢失或覆盖。错误处理与异常捕获
SAX 解析出错(如格式错误、编码问题)会抛出
xml.sax.SAXParseException。建议用 try-except 包裹 parse 调用:try: xml.sax.parse("books.xml", handler) except xml.sax.SAXParseException as e: print(f"XML 解析错误:第{e.getLineNumber()}行,第{e.getColumnNumber()}列 — {e.getMessage()}")进阶:使用 xml.sax.make_parser() 自定义解析器
若需设置 DTD 验证、命名空间支持或自定义错误处理器,可用:
parser = xml.sax.make_parser() parser.setContentHandler(handler) parser.setFeature(xml.sax.handler.feature_namespaces, False) # 关闭命名空间 parser.parse("books.xml")还可通过
parser.setErrorHandler()设置自定义错误处理器。











