Python解析XML时如何保留实体标签而非解析后的内容?
如何在Python解析XML时保留原始实体标签而非展开内容
这个问题确实挺常见的——默认的xml.etree.ElementTree会自动展开XML实体,所以你拿到的是解析后的值而不是原始的实体标签。下面给你两种可行的解决方案,分别基于Python标准库和第三方库,你可以根据情况选择:
方案一:使用Python标准库的SAX解析器
SAX解析器提供了更底层的XML事件处理能力,我们可以通过自定义处理器来捕获未展开的实体引用,而不是让解析器自动替换它们。
import xml.sax class EntityPreservingHandler(xml.sax.ContentHandler): def __init__(self): self.current_tag = None self.tag_content = [] def startElement(self, name, attrs): # 记录当前正在处理的标签 self.current_tag = name def endElement(self, name): if name == "mytag": # 拼接收集到的所有内容(包括实体引用) raw_content = ''.join(self.tag_content) print(f"mytag的原始内容:{raw_content}") # 重置状态,准备处理下一个标签 self.current_tag = None self.tag_content = [] def characters(self, content): # 收集普通文本内容 if self.current_tag == "mytag": self.tag_content.append(content) def skippedEntity(self, name): # 捕获未被展开的实体引用,格式化为&实体名; if self.current_tag == "mytag": self.tag_content.append(f"&{name};") # 初始化SAX解析器 parser = xml.sax.make_parser() parser.setContentHandler(EntityPreservingHandler()) # 禁用外部实体解析,确保实体引用被保留 parser.setFeature(xml.sax.handler.feature_external_ges, False) parser.setFeature(xml.sax.handler.feature_external_pes, False) # 解析你的XML文件 with open("your_xml_file.xml", "r", encoding="utf-8") as xml_file: parser.parse(xml_file)
代码说明:
skippedEntity方法会在解析器遇到未展开的实体时触发,我们在这里把实体引用(比如&exa;)添加到内容列表中。characters方法负责收集标签内的普通文本内容。- 最后在
endElement方法中,我们将收集到的内容拼接起来,就能得到保留原始实体标签的结果。
方案二:使用lxml库(更简洁)
如果你可以安装第三方库,lxml提供了更便捷的方式来禁用实体展开,代码会简洁很多:
首先安装lxml:
pip install lxml
然后使用以下代码解析XML:
from lxml import etree # 创建解析器并禁用实体展开 parser = etree.XMLParser(resolve_entities=False) tree = etree.parse("your_xml_file.xml", parser) root = tree.getroot() for item in root: if item.tag == "mytag": # 获取标签内的原始文本(包含实体引用) raw_content = etree.tostring(item, encoding='unicode', method='text') print(f"mytag的原始内容:{raw_content}")
代码说明:
- 通过
resolve_entities=False告诉lxml解析器不要展开实体。 etree.tostring方法可以直接获取标签内的原始文本内容,包括未展开的实体引用。
内容的提问来源于stack exchange,提问作者FalsinSoft
相关产品推荐
相关产品推荐

