【问题标题】:How to generate XML, UTF-8 with BOM using Python Element Tree?如何使用 Python 元素树生成带有 BOM 的 XML、UTF-8?
【发布时间】:2022-01-31 10:43:20
【问题描述】:

为了为 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,并且我还编写了修复程序 (https://github.com/python/cpython/pull/31043)。

【问题讨论】:

  • 正在禁用带有 xml_declaration=False 的 xml prolog 作为 .write() 参数选项?
  • @MaciejWrobel:不。XML prolog 必须存在。

标签: python xml utf-8 elementtree byte-order-mark


【解决方案1】:

查看 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 的内部是唯一的选择(除了猴子路径模块),编写所需的序言并将 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文件之外,这将是次要的好处。

【讨论】:

  • 谢谢,Maciej。在我看来,write 方法中的 declared_encoding 第 741 行(在编写序言时)应将 utf-8-sig 替换为 utf-8
猜你喜欢
  • 2010-11-25
  • 1970-01-01
  • 1970-01-01
  • 2012-02-12
  • 2011-01-28
  • 1970-01-01
  • 1970-01-01
  • 2015-02-15
  • 1970-01-01
相关资源
最近更新 更多