【问题标题】:ElementTree and unicodeElementTree 和 unicode
【发布时间】:2012-09-03 04:53:41
【问题描述】:

我在一个 xml 文件中有这个字符:

<data>
  <products>
      <color>fumè</color>
  </product>
</data>

我尝试使用以下代码生成 ElementTree 的实例:

string_data = open('file.xml')
x = ElementTree.fromstring(unicode(string_data.encode('utf-8')))

我收到以下错误:

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

(注意:位置不准确,我是从一个较大的 xml 中采样的)。

如何解决?谢谢

【问题讨论】:

  • 附注 - 您的示例数据不正确 - productsproduct

标签: python unicode encoding utf-8 elementtree


【解决方案1】:

您的文件很可能不是 UTF-8。 è 字符可以来自其他编码,例如latin-1

【讨论】:

  • 我确保文件以 utf-8 编码保存。
  • 试过编码'cp-1250',还是不行。 'latin-1' 做到了。谢谢!
【解决方案2】:

您需要将 utf-8 字符串解码为 unicode 对象。所以

string_data.encode('utf-8')

应该是

string_data.decode('utf-8')

假设 string_data 实际上是一个 utf-8 字符串。

总结一下:要从 unicode 对象中获取 utf-8 字符串,您 编码 unicode(使用 utf-8 编码),然后将字符串转换为 unicode 对象,您 解码使用相应编码的字符串。

有关这些概念的更多详细信息,我建议阅读The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets(不是特定于 Python)。

【讨论】:

  • 这并没有改变任何东西,很遗憾
  • OP 的问题是他/她正在尝试处理解码,而不是把它留给 ElementTree 本身......
  • @MartijnPieters:当然,我在旅途中写下了我的答案,应该更仔细地看待这个问题。虽然编码字节串以获得 unicode 肯定是错误的,但这不是(真正的)问题。
  • 你救了我的命 :)。
【解决方案3】:

您是否尝试过使用parse 函数,而不是打开文件...(顺便说一句,.fromstring() 之后需要.read() 才能工作...)

import xml.etree.ElementTree as ET

tree = ET.parse('file.xml')
root = tree.getroot()
# etc...

【讨论】:

    【解决方案4】:

    您确实不需要需要解码 XML 才能使 ElementTree 工作。 XML 带有自己的编码信息(默认为 UTF-8),ElementTree 为您完成工作,输出 unicode:

    >>> data = '''\
    ... <data>
    ...   <products>
    ...       <color>fumè</color>
    ...   </products>
    ... </data>
    ... '''
    >>> x = ElementTree.fromstring(data)
    >>> x[0][0].text
    u'fum\xe8'
    

    如果您的数据包含在文件(类似)对象中,只需将文件名或文件对象直接传递给ElementTree.parse() 函数:

    x = ElementTree.parse('file.xml')
    

    【讨论】:

    • 遗憾的是,有时我们的 XML 没有嵌入编码信息,而 Elementree 弄错了,返回的 strs 中包含损坏的字符。
    • @Kylotan:那么那些 XML 文档有问题。 XML 规范对此非常清楚;除非在 XML 标头中特别说明,否则文档被编码为 UTF8。
    • @Kylotan:您可以使用传递给ElementTree.XMLParser() 函数的ElementTree.XMLParser() 对象覆盖XML 声明,将其用于损坏的XML 输入。
    • @Kylotan:但是,这并不会因为您破坏了 XML 而使我的答案不正确。
    • 好吧,我很难知道 XML 是否有任何问题,因为它似乎在其他地方呈现正常,但我的输出有问题,这就是我所知道的。 (会撤消反对票,但 SO 不允许我这样做。)
    【解决方案5】:

    可能你在使用Requests (HTTP for Humans)时偶然发现了这个问题,response.text默认解码响应,你可以使用response.content获取未解码的数据,因此ElementTree可以自己解码。请记住使用正确的编码。

    更多信息:http://docs.python-requests.org/en/latest/user/quickstart/#response-content

    【讨论】:

    • 一般来说,除非response.text 考虑到response.content 是XML 并遵循相应的标准,例如,读取xml 声明fi,否则您应该将xml 数据(作为字节)直接传递给XML 解析器任何找出字符编码的方法(requests 似乎不太可能这样做,也不应该这样做)。
    【解决方案6】:

    函数open() 不返回string。 而是使用open('file.xml').read()

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-06-26
      • 2013-11-19
      • 1970-01-01
      • 2014-02-02
      • 1970-01-01
      • 1970-01-01
      • 2016-03-01
      相关资源
      最近更新 更多