【问题标题】:Writing XML to file corrupts files in python将 XML 写入文件会损坏 python 中的文件
【发布时间】:2010-12-19 17:37:15
【问题描述】:

我正在尝试将内容从 xml.dom.minidom 对象写入文件。简单的想法是使用'writexml'方法:

import codecs

def write_xml_native():
    # Building DOM from XML
    xmldoc = minidom.parse('semio2.xml')
    f = codecs.open('codified.xml', mode='w', encoding='utf-8')
    # Using native writexml() method to write
    xmldoc.writexml(f, encoding="utf=8")
    f.close()

问题在于它破坏了文件中的非拉丁编码文本。另一种方法是获取文本字符串并将其显式写入文件:

def write_xml():
    # Building DOM from XML
    xmldoc = minidom.parse('semio2.xml')
    # Opening file for writing UTF-8, which is XML's default encoding
    f = codecs.open('codified3.xml', mode='w', encoding='utf-8')
    # Writing XML in UTF-8 encoding, as recommended in the documentation
    f.write(xmldoc.toxml("utf-8"))
    f.close()

这会导致以下错误:

Traceback (most recent call last):
  File "D:\Projects\Semio\semioparser.py", line 45, in <module>
    write_xml()
  File "D:\Projects\Semio\semioparser.py", line 42, in write_xml
    f.write(xmldoc.toxml(encoding="utf-8"))
  File "C:\Python26\lib\codecs.py", line 686, in write
    return self.writer.write(data)
  File "C:\Python26\lib\codecs.py", line 351, in write
    data, consumed = self.encode(object, self.errors)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xd0 in position 2064: ordinal not in range(128)

如何将 XML 文本写入文件?我错过了什么?

编辑。通过添加解码语句修复错误: f.write(xmldoc.toxml("utf-8").decode("utf-8")) 但俄罗斯符号仍然被破坏。

在解释器中查看时文本没有损坏,但在文件中写入时。

【问题讨论】:

  • 只是一个想法:您确定您没有错误地查看文件吗?也许读者期待另一种编码而不是 utf-8,它看起来很无聊。
  • @Nubsis 这正是发生的事情。观众一直期待 ASCII 编码。不过我会保留这个线程,因为使用 .decode() 也是问题所在。谢谢!

标签: python xml file-io minidom


【解决方案1】:

嗯,虽然这应该可行:

xml = minidom.parse("test.xml")
with codecs.open("out.xml", "w", "utf-8") as out:
    xml.writexml(out)

你也可以试试:

with codecs.open("test.xml", "r", "utf-8") as inp:
    xml = minidom.parseString(inp.read().encode("utf-8"))
with codecs.open("out.xml", "w", "utf-8") as out:
    xml.writexml(out)

更新:如果你用字符串对象构造 xml,你应该在传递给 minidom 解析器之前对其进行编码,如下所示:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import codecs
import xml.dom.minidom as minidom

xml = minidom.parseString(u"<ru>Тест</ru>".encode("utf-8"))
with codecs.open("out.xml", "w", "utf-8") as out:
    xml.writexml(out)

【讨论】:

  • 感谢您的回答。我已经测试了你所有的代码,没有一个对我有用。即使是与打开 XML 文件无关的最后一段,也将俄罗斯字符串翻译成无意义的。这意味着问题在于将 urf-8 写入文件。还有什么想法吗?
  • @martinthenext:我几乎可以肯定你得到了有效的“utf-8”(所有 3 个示例对我来说都很好,在 windows 和 linux 以及 python 2.5、2.6 和 2.7 上)或你的python安装坏了;截图如下:img190.imageshack.us/img190/9072/minidom.png
  • 等等,解释器本身的输出很好,没有问题。写入文件时会损坏。我该如何解决这个问题?
  • @martinthenext:请注意屏幕截图底部的第二行:它显示生成的文件内容(从 utf -> cp866 重新编码,即控制台编码)。你说的“损坏”是什么意思,你如何检查这个?
  • 好吧,'损坏'意味着俄语字符被垃圾替换。
【解决方案2】:

试试这个:

with open("codified.xml", "w") as f:
    f.write(xmldoc.toxml("utf-8").decode("utf-8"))

这对我有用(不过在 Python 3 下)。

【讨论】:

  • 如果你 x = codecs.open("semio2.xml", encoding="utf-8")xmldoc = minidom.parse(x) 会发生什么?
  • 上面写着UnicodeEncodeError: 'ascii' codec can't encode character u'\ufeff' in position 0: ordinal not in range(128)。我不明白为什么。
  • @martinthenext:您收到此错误是因为您提供了 minidom unicode 字符串(虽然它只接受二进制)。如果您以“utf-8”模式打开文件,您应该在解析之前将其内容编码为“utf-8”。
猜你喜欢
  • 1970-01-01
  • 2021-09-12
  • 2016-06-23
  • 2020-01-27
  • 2019-01-09
  • 1970-01-01
  • 2014-07-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多