Python 3.9中ZipFile生成XML时°符号转义问题求助
问题原因
这个转义不是ZipFile导致的,是xml.etree.ElementTree的默认行为——它会把XML属性值中的非ASCII字符自动转成实体引用(比如°转成°),目的是兼容仅支持ASCII编码的旧版XML解析器,但我们明确用UTF-8编码时完全不需要这个行为。
解决方案
有两种标准库内的解决方式,都可以保留原符号:
方式一:指定encoding为unicode后手动编码
修改ET.tostring的调用参数,先获取未转义的Unicode字符串,再编码为UTF-8字节写入压缩包:
import xml.etree.ElementTree as ET from zipfile import ZipFile import datetime def gen_zip(): root = ET.Element("MyXml") batch = ET.SubElement( root, "Batch", Id="1", DateTime=datetime.strftime(datetime.now(), "%Y%m%d%H%M%S"), Value = "Invoice n°123456789" ) zf = ZipFile("myzip.zip", "w") # 获取未转义的Unicode字符串,再编码为UTF-8 xml_content = ET.tostring(root, encoding='unicode') zf.writestr("file.xml", xml_content.encode('utf-8')) zf.close() return None
方式二:使用ElementTree对象写入
通过ET.ElementTree的write方法直接生成UTF-8编码的XML内容,该方法默认不会转义非ASCII字符(当指定编码为UTF-8时):
import xml.etree.ElementTree as ET from zipfile import ZipFile import datetime import io def gen_zip(): root = ET.Element("MyXml") batch = ET.SubElement( root, "Batch", Id="1", DateTime=datetime.strftime(datetime.now(), "%Y%m%d%H%M%S"), Value = "Invoice n°123456789" ) zf = ZipFile("myzip.zip", "w") # 用ElementTree对象生成UTF-8编码的XML tree = ET.ElementTree(root) xml_buffer = io.BytesIO() tree.write(xml_buffer, encoding='utf-8', xml_declaration=True) zf.writestr("file.xml", xml_buffer.getvalue()) zf.close() return None
验证结果
修改后生成的XML内容会保留原符号:
<?xml version='1.0' encoding='utf-8'?> <MyXml> <Batch Id="1" DateTime="20221207093739" Value="Invoice n°123456789"/> </MyXml>
内容的提问来源于stack exchange,提问作者orville
相关产品推荐
相关产品推荐

