【问题标题】:UnicodeEncodeError: how to encode xml tree parsed with ElementTreeUnicodeEncodeError:如何对使用 ElementTree 解析的 xml 树进行编码
【发布时间】:2015-03-31 00:18:59
【问题描述】:

我有一个具有这种结构的 XML 文件:

<doc>
 <content>
  <one>Title</one>
  <two>bla bla bla bla</two>
 </content>
 <content>
  <one>Title</one>
  <two>bla bla bla bla</two>
 </content>
 ...
</doc>

我通过 nltk 包在 python 中读取文件并使用 ElementTree 解析树,如下所示:

from xml.etree.ElementTree import ElementTree
wow = nltk.data.find('/path/file.xml')
tree = ElementTree().parse(wow)

然后我尝试从“两个”元素中打印一些东西,如下所示:

for i, content in enumerate(tree.findall('content')):
    for two in content.findall('two'):
        if 'keyword' in str(two.text):
            print("%s" % (two.text))

我得到了臭名昭著的错误:

Traceback (most recent call last):
   File "<stdin>", line 3, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe0' in position 21: ordinal not in range(128)

我知道这是由于 ascii 和 UTF-8 编码的不兼容问题。 XML 编码为 UTF-8。我尝试了在stackoverflow上找到的几种解决方案(主要是:我尝试在这里和那里添加.encode('UTF-8').decode('UTF-8'),或者在data.find中添加encoding='utf-8'),但我发现的示例与我的完全不同,所以我没有设法使这些答案适应我的情况:正如您想象的那样,我是 python 新手。

如何避免错误并打印我需要的内容?谢谢。

【问题讨论】:

  • try if u'keyword' in unicode(two.text): -- 当你在一个对象上调用str 时,你会将该对象强制转换为使用 ascii 编解码器的字符串格式。如果您的对象包含非 ascii 元素,则会引发错误。
  • 也不需要调用unicode -- two.text 应该已经是 unicode(如果不是,则解码无论如何都需要显式编解码器,并且应该更早发生)。
  • 感谢 duhaime 和 Alex,str 正是导致问题的原因!我不知道str 将文本强制转换为ascii。

标签: python xml encoding utf-8 nltk


【解决方案1】:

所以 two.text 应该是一个 Unicode 字符串,而你想 print 它——为什么不检查一下

if u'keyword' in two.text:

然后如果合适的话

print(two.text)

没有费力的字符串化?如果您的终端设置正确,它将告诉 Python 使用哪种编码向其发送正确表示该字符串的字节以用于显示目的。

通常最好在 Unicode 中统一工作(这就是为什么str 在 Python 3 中变成 unicode 的原因:-)并且只在输入上解码,在输出上编码——而且 I/O 系统通常会处理解码和编码对你来说非常透明。

根据您的 Python 版本(您没有告诉我们),您可能需要进行一些显式编码 - 尽快,而不是在当天晚些时候。例如,如果你坚持使用 Python 2,而 wow 是一个 Unicode 字符串(我认为取决于你的 nltk 版本),那么

tree = ElementTree().parse(wow.encode('utf8'))

可能会更好;如果wow 已经是一个来自 nltk 的 utf8 编码的字节字符串,那么显然您不需要再次对其进行编码:-)。

为消除此类疑虑,print(repr(wow[:30])) 或附近会告诉您更多信息。 print(sys.version) 会告诉你 Python 的版本,这样你就可以反过来告诉我们,因为即使它通常是绝对重要的信息,但似乎很少有人这样做!-)

【讨论】:

  • 错误似乎指向第 3 行,所以这不是暗示 str() 调用导致了问题吗?
  • @duhaime 当然,str(...) 发生在print 中等效的% 格式之前——两者都尝试将two.text 编码为ascii。两者都不是必需的!看我的回答:没有str 电话,print 也没有%
  • 对不起,我忘了说,我的python版本是2.7,切割str工作得很好!问题是我正在使用和改编取自 nltk 书中的代码,我认为 str 是至关重要的,但事实并非如此。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-20
  • 2013-03-15
  • 1970-01-01
  • 2018-02-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多