迭代SAX

时间:2011-09-09 10:24:31

标签: python sax

我有一个这样的xml(只是一个例子):

<xml>
  <page>
    <lol>
    </lol>
    <lel>
    </lel>
  </page>
  <page>
    <lol>
    </lol>
    <lel>
    </lel>
  </page>
  <page>
    <lol>
    </lol>
    <lel>
    </lel>
  </page>
</xml>

我需要一种方法来做这样的事情:

#Sax code

for page in something:
  parse(page)

我如何用sax做到这一点?

xml文件包含30GB的数据。

4 个答案:

答案 0 :(得分:2)

请勿使用SAX,而是使用ElementTree

from xml.etree import cElementTree as ET

for event, elem in ET.iterparse("/path/to/your/file"):
    if elem.tag == 'page':
        # do your processing
        elem.clear()

elem.clear()调用非常重要,否则您将把所有已处理的元素保留在内存中并最终消耗掉所有RAM。元素对象是轻量级的DOM对象,因此与SAX相比,它们非常易于使用。

如果单个page元素已经太大而无法满足您的记忆,则必须恢复为SAX,但我从您的示例中假设有许多小page元素而不是少数大的。

答案 1 :(得分:1)

使用xml.sax执行此操作的最有效和pythonic方法是使用 parser.feed()方法。

示例:

parser = xml.sax.make_parser()
parser.setContentHandler(YourContentHandler)

f = open('terribly_large.xml', 'r')
for line in f.xreadlines():
    parser.feed(line)

这确保您既可以逐步读取文件,也可以逐步解析文件。

最终的内存占用量应该很小。

答案 2 :(得分:0)

您可以在线程中使用sax解析器。当它检测到完整的fage时,会将其推送到队列中。在主线程中,遍历队列。

答案 3 :(得分:-2)

使用Dom而不是Sax,sax会在出现像启动元素或文本这样的兴趣内容时保持火灾事件,但如果你想迭代文件,请使用dom link可以帮助你。

更新:

30GB必须使用SAX