ElementTree的替代XML解析器可以缓解UTF-8问题?

Kek*_*koa 9 python xml utf-8 elementtree

我正在使用elementtree.parse()函数解析一些XML.它工作,除了一些utf-8字符(128字节以上的单字节字符).我看到默认的解析器是XMLTreeBuilder,它基于expat.

是否有一个我可以使用的替代解析器可能不那么严格并允许utf-8字符?

这是我使用默认解析器得到的错误:

ExpatError: not well-formed (invalid token): line 311, column 190
Run Code Online (Sandbox Code Playgroud)

导致此字符的字符是单字节x92(十六进制).我不确定这甚至是一个有效的utf-8字符.但处理它会很好,因为大多数文本编辑器将其显示为:í

编辑:角色的上下文是:canít,我认为它应该是一个花哨的撇号,但在十六进制编辑器中,相同的序列是:63 61 6E 92 74

Joh*_*hin 15

我将从这个问题开始:"我可以使用的替代解析器可能不那么严格并且允许使用utf-8字符吗?"

所有XML解析器都将接受以UTF-8编码的数据.实际上,UTF-8是默认编码.

XML文档可以以如下声明开头:

`<?xml version="1.0" encoding="UTF-8"?>`
Run Code Online (Sandbox Code Playgroud)

或者像这样: <?xml version="1.0"?> 或者根本没有声明......在每种情况下,解析器都将使用UTF-8解码文档.

但是你的数据不是用UTF-8编码的......它可能是Windows-1252,也就是cp1252.

如果编码不是UTF-8,则创建者应该包含声明(或者收件人可以添加一个声明),或者收件人可以将数据转码为UTF-8.以下展示了哪些有效,哪些无效:

>>> import xml.etree.ElementTree as ET
>>> from StringIO import StringIO as sio

>>> raw_text = '<root>can\x92t</root>' # text encoded in cp1252, no XML declaration

>>> t = ET.parse(sio(raw_text))
[tracebacks omitted]
xml.parsers.expat.ExpatError: not well-formed (invalid token): line 1, column 9
# parser is expecting UTF-8

>>> t = ET.parse(sio('<?xml version="1.0" encoding="UTF-8"?>' + raw_text))
xml.parsers.expat.ExpatError: not well-formed (invalid token): line 1, column 47
# parser is expecting UTF-8 again

>>> t = ET.parse(sio('<?xml version="1.0" encoding="cp1252"?>' + raw_text))
>>> t.getroot().text
u'can\u2019t'
# parser was told to expect cp1252; it works

>>> import unicodedata
>>> unicodedata.name(u'\u2019')
'RIGHT SINGLE QUOTATION MARK'
# not quite an apostrophe, but better than an exception

>>> fixed_text = raw_text.decode('cp1252').encode('utf8')
# alternative: we transcode the data to UTF-8

>>> t = ET.parse(sio(fixed_text))
>>> t.getroot().text
u'can\u2019t'
# UTF-8 is the default; no declaration needed
Run Code Online (Sandbox Code Playgroud)