You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:08:59