【发布时间】:2012-07-09 03:52:59
【问题描述】:
我一直致力于解析外部 XML 文件的代码。其中一些文件很大,高达千兆字节的数据。不用说,这些文件需要被解析为流,因为将它们加载到内存中效率太低,并且经常导致 OutOfMemory 问题。
我使用了 miniDOM、ElementTree、cElementTree 库,目前正在使用 lxml。
现在我有一个使用lxml.etree.iterparse 的有效的、非常节省内存的脚本。问题是我需要解析的一些 XML 文件包含编码错误(它们宣传为 UTF-8,但包含不同编码的字符)。使用lxml.etree.parse 时,可以使用自定义解析器的recover=True 选项来解决此问题,但iterparse 不接受自定义解析器。 (另见:this question)
我当前的代码如下所示:
from lxml import etree
events = ("start", "end")
context = etree.iterparse(xmlfile, events=events)
event, root_element = context.next() # <items>
for action, element in context:
if action == 'end' and element.tag == 'item':
# <parse>
root_element.clear()
iterparse 遇到错误字符时出错(在本例中为 ^Y):
lxml.etree.XMLSyntaxError: Input is not proper UTF-8, indicate encoding !
Bytes: 0x19 0x73 0x20 0x65, line 949490, column 25
我什至不想解码这些数据,我可以放弃它。但是我不知道有什么方法可以跳过该元素 - 我在 try/except 语句中尝试了 context.next 和 continue。
任何帮助将不胜感激!
更新
一些附加信息: 这是 iterparse 失败的那一行:
<description><![CDATA:[musea de la photographie fonds mercator. Met meer dan 80.000 foto^Ys en 3 miljoen negatieven is het Muse de la...]]></description>
根据etree,错误发生在字节0x19 0x73 0x20 0x65。
根据 hexedit,19 73 20 65 转换为 ASCII .s e
这个地方的. 应该是一个撇号(照片)。
我还找到了this question,它没有提供解决方案。
【问题讨论】:
-
你尝过美味的汤吗?
-
执行预处理步骤来纠正编码是否可行?您甚至可以使用 StringIO 对象在管道中执行此操作并将输出提供给 etree。
-
@DanatheSane 当然可以,有什么建议可以解决这个问题吗?
-
@Rik 如果您将一些代码放在一起来解析标签、属性和内容解析,您可以将有问题的输入提供给 chardet(请参阅stackoverflow.com/questions/436220/…)并随时重新编写文件。我不确定文档中的编码问题在哪里,但如果它们有些孤立,这不会产生太多开销。
-
请发布一个完整的 XML 文档,其中包括您的顶级标签和 DTD(如果有)以及片段,以便其他人可以测试您正在测试的相同内容。此外,如果您可以在错误之前显示几个字节,这可能会有所帮助(这样我们就可以看到我们是否有半个 UTF-8 字符或其他内容)。
标签: python xml encoding iterparse