如何使用Python Element Tree 生成XML, UTF-8 with BOM?
How to generate XML, UTF-8 with BOM using Python Element Tree?
为 ASP.NET 生成资源 XML 文件,第三方工具需要 BOM(迁移到新版本的工具时)。同时,它需要像 <?xml version='1.0' encoding='utf-8'?>
.
这样的 XML prolog
问题是在使用 ElementTree 命令时...
tree.write(lang_resx_fpath, encoding='utf-8')
生成的文件不包含 BOM。使用命令时...
tree.write(lang_resx_fpath, encoding='utf-8-sig')
结果确实包含BOM;但是,XML 序言包含 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, and I have also written the fix (https://github.com/python/cpython/pull/31043).
查看 ElementTree.write 的源代码表明 prolog 在那里被硬编码 (https://github.com/python/cpython/blob/main/Lib/xml/etree/ElementTree.py or permalink 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 文件之外,这将是次要的好处。
为 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')
结果确实包含BOM;但是,XML 序言包含 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, and I have also written the fix (https://github.com/python/cpython/pull/31043).
查看 ElementTree.write 的源代码表明 prolog 在那里被硬编码 (https://github.com/python/cpython/blob/main/Lib/xml/etree/ElementTree.py or permalink 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 文件之外,这将是次要的好处。