我有一个大的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
我想指出计算机在执行期间冻结,因此这可能与内存消耗有关,如下所述。
答案 0 :(得分:7)
尝试使用更易于使用的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
答案 1 :(得分:6)
我强烈建议在这里使用SAX解析器。我不建议在任何大于几兆字节的XML文档上使用minidom
;我已经看到它在大约10MB的XML文档中使用大约400MB的RAM读取。我怀疑你遇到的问题是由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
或{{1这些处理SAX解析器在读取XML文档时生成的事件。
SAX是一种比DOM更“低级”的处理XML的方法;除了从文档中提取相关数据外,您的ContentHandler还需要开展工作,跟踪当前内部的元素。然而,从好处来看,由于SAX解析器不会将整个文档保留在内存中,因此它们可以处理任何大小的XML文档,包括那些比您大的文档。
我没有尝试过在这种大小的XML文档上使用lxml等DOM解析器,但我怀疑lxml仍然需要相当长的时间并使用大量内存来解析XML文档。如果每次运行代码时都需要等待它读取84MB XML文档,那么这可能会降低开发速度。
最后,我不相信你提到的希腊语,西班牙语和阿拉伯语字符会引起问题。
答案 2 :(得分:3)
有两种XML解析器(这适用于任何语言)。
DOM解析(这是你正在使用的)。在这种类型中,整个XML文件被读入内存结构,然后通过方法访问。
SAX解析。这是一种解析算法,它以逐步的方式读取每段XML。这种技术可以让您更好地检测和处理错误。
一般来说,DOM比SAX更容易,因为许多细节都是通过其原生方法来处理的。
SAX有点挑战,因为你必须编写SAX解析&#34;运行的方法。在浏览XML文档时。