优雅地从expat中的解析错误中恢复

时间:2011-03-21 17:52:56

标签: python xml parsing unicode expat-parser

XML应该是严格的,因此XML中不允许使用某些Unicode字符。但是我正在尝试使用通常包含这些字符的RSS源,我想要避免无效字符的解析错误或者从它们中优雅地恢复并且无论如何都要呈现文档。

在此处查看示例(无论如何在3月21日):http://feeds.feedburner.com/chrisblattman

在XML Feed中处理unicode的推荐方法是什么?检测字符并用空字节替换,编辑解析器或其他一些方法?

2 个答案:

答案 0 :(得分:4)

看起来RSS Feed包含垂直制表符\x0c,这是非法per the XML 1.0 spec

我的建议是在将数据传递给expat之前过滤掉非法字符,而不是试图捕获错误并恢复。这是一个过滤掉非法Unicode字符的例程。我在您的chrisblattman.xml RSS Feed上测试了它:

import re
from xml.parsers import expat

# illegal XML 1.0 character ranges
# See http://www.w3.org/TR/REC-xml/#charsets
XML_ILLEGALS = u'|'.join(u'[%s-%s]' % (s, e) for s, e in [
    (u'\u0000', u'\u0008'),             # null and C0 controls
    (u'\u000B', u'\u000C'),             # vertical tab and form feed
    (u'\u000E', u'\u001F'),             # shift out / shift in
    (u'\u007F', u'\u009F'),             # C1 controls
    (u'\uD800', u'\uDFFF'),             # High and Low surrogate areas
    (u'\uFDD0', u'\uFDDF'),             # not permitted for interchange
    (u'\uFFFE', u'\uFFFF'),             # byte order marks
    ])

RE_SANITIZE_XML = re.compile(XML_ILLEGALS, re.M | re.U)

# decode, filter illegals out, then encode back to utf-8
data = open('chrisblattman.xml', 'rb').read().decode('utf-8')
data = RE_SANITIZE_XML.sub('', data).encode('utf-8')

pr = expat.ParserCreate('utf-8')
pr.Parse(data)

更新:这是关于XML字符有效性的a Wikipedia page。我的正则表达式过滤掉了C1控制范围,但您可能希望根据应用程序允许这些字符。

答案 1 :(得分:1)

您可以尝试Beautiful Soup解析HTML / XML文档,即使它们格式不正确。