【问题标题】:Unicode error when passing unicode object to XML parser将 unicode 对象传递给 XML 解析器时出现 Unicode 错误
【发布时间】:2011-11-15 22:35:41
【问题描述】:

我正在尝试读取包含 xml 和 unicode 的 gzip 文件,但出现错误。我使用的代码是:

import gzip
import xml

path = "index.mjml.gz"
gzFile = gzip.open(path, mode='r')
gzContents = gzFile.read()
gzFile.close()

unicodeContents = gzContents.encode('utf-8')
xmlContent = xml.dom.minidom.parseString(unicodeContents)
# Do stuff with xmlContent

当我运行此代码时,我收到以下错误(在以 xmlContent 开头的行上失败)

/Library/Frameworks/EPD64.framework/Versions/7.1/lib/python2.7/xml/dom/minidom.pyc in parseString(string, parser)
   1922     if parser is None:
   1923         from xml.dom import expatbuilder
-> 1924         return expatbuilder.parseString(string)
   1925     else:
   1926         from xml.dom import pulldom

/Library/Frameworks/EPD64.framework/Versions/7.1/lib/python2.7/xml/dom/expatbuilder.pyc in parseString(string, namespaces)
    938     else:
    939         builder = ExpatBuilder()
--> 940     return builder.parseString(string)
    941 
    942 

/Library/Frameworks/EPD64.framework/Versions/7.1/lib/python2.7/xml/dom/expatbuilder.pyc in parseString(self, string)
    221         parser = self.getParser()
    222         try:
--> 223             parser.Parse(string, True)
    224             self._setup_subset(string)
    225         except ParseEscape:

UnicodeEncodeError: 'ascii' codec can't encode character u'\xe9' in position 1141336: ordinal not in range(128)

我找到了与 Reading utf-8 characters from a gzip file in python 类似的先前答案,但我仍然收到错误消息。

xml解析器有问题吗?

(我使用的是 Python 2.7。?)

【问题讨论】:

  • "xml解析器有问题吗?"请发布堆栈跟踪,让我们知道错误发生在哪一行。很难判断异常是发生在.decode(...) 还是.parseString(...)。如果错误发生在 .decode(...) 上,那么直接的问题不在于 XML 解析器。
  • unicodeContents 应该设置为gzContents.decode('utf-8') 还是gzContants.decode('utf-8')?帖子中的拼写让我大吃一惊,尤其是因为错误消息似乎根本与该错误无关。
  • @Edwin 我试图指出失败发生在最后一行——以xmlContent 开头的行。我将添加剩余的回溯。
  • @MikeSamuel 是的,这是我将代码转换为简单示例时出现的拼写错误。正如我所提到的,错误发生在以xmlContent 开头的行上。
  • @ulidtko:查看回溯中的路径。不,它不在 Windows 上,与操作系统无关。

标签: python unicode xml-parsing


【解决方案1】:

您不能将 unicode 字符串传递给 xml.dom.minidom.parseString

它必须是一个适当编码的字节串:

>>> import xml.dom.minidom as xmldom
>>>
>>> source = u"""\
... <?xml version="1.0" encoding="utf-8"?>
... <root><text>Σὲ γνωρίζω ἀπὸ τὴν κόψη</text></root>
... """
>>> doc = xmldom.parseString(source.encode('utf-8'))
>>> print doc.getElementsByTagName('text')[0].toxml()
<text>Σὲ γνωρίζω ἀπὸ τὴν κόψη</text>

编辑

澄清一下 - 从 gzip 压缩的 xml 文件中读取的流应该直接传递给解析器,而不是尝试对其进行编码或解码:

import gzip
import xml

path = "index.mjml.gz"
gzFile = gzip.open(path, mode='r')
gzContents = gzFile.read()
gzFile.close()

xmlContent = xml.dom.minidom.parseString(gzContents)

解析器将从文件开头的 xml 声明中读取编码(如果没有,则假定为“utf-8”)。然后它可以使用它来将内容解码为 un​​icode。

【讨论】:

  • +1 事实上,任何 xml 解析器的输入都应该是字节流;解析器的工作是使用字节流前面的声明(如果有)来解码 xml 字节流。您的脚本不需要知道编码是什么。
  • 所以我按照@ekhumoro 的建议将decode 更改为encode,但我仍然遇到同样的错误。 (说实话,我对编码和解码的区别不是很了解。)
  • @Jeremy。抱歉 - 我也许应该让事情更清楚。您不需要使用encodedecode - 只需将从gzip 压缩文件(即gzContents)读取的字节直接传递给xml 解析器;它将处理解码。
  • @ekhumoro 这就是我最初尝试的。我已将问题进一步简化为使用 emdash 打印。我会用一个更精确的例子发布一个不同的问题。
  • @ekhumoro,嗨,我有一个与 Suds 类似的问题,它使用 python xml 进行肥皂包络解析/构造,请你看看这个问题:stackoverflow.com/questions/15339141/…,让我知道你的答案基于你的经验。提前致谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-20
  • 2016-01-25
  • 1970-01-01
  • 1970-01-01
  • 2019-04-30
  • 2015-11-21
相关资源
最近更新 更多