我正在尝试使用
Python的lxml库解析超过2GB的XML文件.不幸的是,XML文件没有一个告诉字符编码的行,所以我必须手动设置它.虽然遍历文件,但是仍然有一些奇怪的字符在一段时间内出现.
我不知道如何确定该行的字符编码,但此外,lxml将从for循环的范围引发XMLSyntaxError.如何正确地捕捉这个错误,并正确处理?这是一个简单的代码片段:
from lxml import etree etparse = etree.iterparse(file("my_file.xml",'r'),events=("start",),encoding="CP1252") for event,elem in etparse: if elem.tag == "product": print "Found the product!" elem.clear()
这最终会产生错误:
XMLSyntaxError:PCDATA无效字符值31,行1565367,第50列
该文件的一行如下所示:
% sed -n "1565367 p" my_file.xml <romance_copy>Ravioli Florentine. Tender Ravioli Filled With Creamy Ricotta Cheese And
填充的“F”实际上在我的终端中看起来像这样:
在这里做的正确的事情是确保XML文件的创建者确保:
A.)声明了文件的编码
B.)XML文件格式良好(无无效字符控制字符,没有无效的字符不落入编码方案,所有元素都已正确关闭等)
C.)如果要确保某些属性/元素存在,具有特定值或对应于某种格式,请使用DTD或XML模式(注意:这将执行性能命中)
A.)声明了文件的编码
B.)XML文件格式良好(无无效字符控制字符,没有无效的字符不落入编码方案,所有元素都已正确关闭等)
C.)如果要确保某些属性/元素存在,具有特定值或对应于某种格式,请使用DTD或XML模式(注意:这将执行性能命中)
所以,现在你的问题.当您使用它解析XML时,LXml支持一大堆参数.你会想看看这两个论点:
– >恢复 – >努力解析破碎的XML
– > huge_tree – >禁用安全限制并支持非常深的树和非常长的文本内容(仅影响libxml2 2.7)
他们会在某种程度上帮助你,但某些无效的字符可能无法恢复,所以再次确保文件正确写入是您最好打赌清理/正常工作的代码.
啊,还有一件事. 2GB是巨大的我假设你有这个文件中的类似元素的列表(示例列表的图书).尝试在操作系统上使用正则表达式表达式分割文件,然后启动多个进程来分割部分.这样,您将能够在您的盒子上使用更多的核心,处理时间将会下降.当然,你必须处理将结果合并在一起的复杂性.我不能为你做这个交易,而是想把它交给你,作为“思想的食物”
添加帖子:
如果您无法控制输入文件,并且其中有不良字符,我将尝试通过在将其解析为文件之前迭代字符串来替换/删除这些不良字符.这里是删除Unicode control characters that you wont need的代码示例:
#all unicode characters from 0x0000 - 0x0020 (33 total) are bad and will be replaced by "" (empty string) for line in fileinput.input(xmlInputFileLocation,inplace=1): for pos in range(0,len(line)): if unichr(line[pos]) < 32: line[pos] = None print u''.join([c for c in line if c])