我有一个大的XML文件(84MB左右),这是这种形式:
<books>
<book>...</book>
....
<book>...</book>
</books>
我的目标是提取每一个书,并得到其属性。 我试图解析它(因为我与其他XML文件一样)如下:
from xml.dom.minidom import parse, parseString
fd = "myfile.xml"
parser = parse(fd)
## other python code here
但代码似乎在解析指令失败。 为什么会出现这种情况,如何能我解决这个问题?
我要指出的是,文件可能包含希腊语,西班牙语和阿拉伯语字符。
这是输出我在IPython中得到:
In [2]: fd = "myfile.xml"
In [3]: parser = parse(fd)
Killed
我想指出的是,计算机执行期间冻结,所以如下所述这可能与内存消耗。
我强烈建议在这里使用SAX解析器。 我不建议使用minidom
上的任何XML文档超过几百兆大; 我已经看到了它使用有关,这是关于大小为10MB的XML文档中的RAM读取400MB。 我怀疑你有正在造成的问题minidom
请求太多内存。
Python带有一个XML SAX解析器。 要使用它,这样做以下。
from xml.sax.handlers import ContentHandler
from xml.sax import parse
class MyContentHandler(ContentHandler):
# override various ContentHandler methods as needed...
handler = MyContentHandler()
parse("mydata.xml", handler)
你ContentHandler
子类将覆盖各种方法的ContentHandler (如startElement
, startElementNS
, endElement
, endElementNS
或characters
。SAX解析器,因为它在读取XML文档生成了这些处理事件。
SAX是一种更“低级别”的方式来处理XML比DOM; 除了从文件中拉出相关数据,您的ContentHandler将需要做的是什么元素目前的内部工作保持跟踪。 上档方面,但是,作为SAX解析器不把整个文件在内存中,他们能够处理潜在的任何大小的XML文档,包括那些比你大。
使用DOM解析器如这种规模的XML文档LXML我还没有尝试过其他的,但我怀疑LXML仍然需要相当长的时间和使用的内存相当数量的解析XML文档。 如果每次你运行你的代码时,你必须等待它的84MB XML文档中读到,可以减缓你的发展。
最后,我不相信你提到会产生问题的希腊,西班牙和阿拉伯字符。
试着用LXML哪个更易于使用。
#!/usr/bin/env python
from lxml import etree
with open("myfile.xml") as fp:
tree = etree.parse(fp)
root = tree.getroot()
print root.tag
for book in root:
print book.text
有2种XML解析器(这适用于任何语言)。
DOM解析(这是你使用的是什么)。 在这种类型的整个XML文件被读入存储器中的结构,然后通过方法来访问。
SAX解析。 这是一个分析算法,其读取在一个逐步的方式每一块XML的。 这种技术将让你更好地检测和处理错误。
一般来说DOM比SAX更容易,因为很多的坚韧不拔的细节是由它的本地方法处理。
SAX是一个更大的挑战了一下,因为你必须代码的方法是,SAX解析过程中“跑”是XML文档的步行路程。