提问人:pepr 提问时间:1/31/2022 最后编辑:pepr 更新时间:2/1/2022 访问量:982
如何使用 Python 元素树生成带有 BOM 的 XML、UTF-8?
How to generate XML, UTF-8 with BOM using Python Element Tree?
问:
要为 ASP.NET 生成资源 XML 文件,第三方工具需要 BOM(迁移到工具的新版本时)。同时,它需要像 .<?xml version='1.0' encoding='utf-8'?>
问题是,当使用 ElementTree 命令时...
tree.write(lang_resx_fpath, encoding='utf-8')
生成的文件不包含 BOM。使用命令时...
tree.write(lang_resx_fpath, encoding='utf-8-sig')
结果确实包含物料清单;但是,XML prolog 包含 .encoding='utf-8-sig'
我应该如何生成同时包含 BOM 和 ?encoding='utf-8'
更新:
我通过再次读取、替换和写入文件来解决它,就像这样......
with open(lang_resx_fpath, 'r', encoding='utf-8-sig') as f:
content = f.read()
content = content.replace("encoding='utf-8-sig'", "encoding='utf-8'")
with open(lang_resx_fpath, 'w', encoding='utf-8-sig') as f:
f.write(content)
无论如何,有没有更清洁的解决方案?
更新:我已经创建了 https://bugs.python.org/issue46598,并且还编写了修复程序(https://github.com/python/cpython/pull/31043)。
答:
查看 ElementTree.write 的源代码显示 prolog 在那里是硬编码的(https://github.com/python/cpython/blob/main/Lib/xml/etree/ElementTree.py 或永久链接 https://github.com/python/cpython/blob/ee0ac328d38a86f7907598c94cb88a97635b32f8/Lib/xml/etree/ElementTree.py)。因此,可能使用 ET 的内部结构是唯一的选择(除了 monkey-pathing 模块),以编写所需的前导码并将 BOM 保存在文件中:
import xml.etree.ElementTree as ET
qnames, namespaces = ET._namespaces(tree._root, None)
with open(lang_resx_fpath,'w',encoding='utf-8-sig') as f:
f.write("<?xml version='1.0' encoding='utf-8'?>\n" )
ET._serialize_xml(f.write,
tree._root, qnames, namespaces,
short_empty_elements=False)
可能它并不比您的解决方案更优雅(也许它甚至不那么优雅)。唯一的优点是它不需要两次写入文件,除了一些巨大的XML文件之外,这将是一个小的好处。
评论
declared_encoding
write
utf-8-sig
utf-8
评论
xml_declaration=False