Python xml.sax模块怎么用 SAX事件驱动解析教程

14次阅读

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

Python xml.sax模块怎么用 SAX事件驱动解析教程

Python 的 xml.sax 模块是基于事件驱动的 XML 解析器,适合处理大文件、内存受限场景,不加载整个文档到内存,而是边读边触发回调。核心在于自定义一个继承 xml.sax.ContentHandler处理器类,并重写其中的方法来响应开始标签、结束标签、文本内容等事件。

创建自定义 ContentHandler 处理器

你需要定义一个类,继承 xml.sax.ContentHandler,并至少实现以下常用方法:

  • startElement(name, attrs):遇到起始标签时调用,name 是标签名,attrsxml.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.sax 

class 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() 设置自定义错误处理器。

text=ZqhQzanResources