如何围绕SAX Parser包装适当的生成器函数

S.L*_*ott -4 python sax

我有35.5Mb .XLSM文件.当实际可用内容被扩展时,它会在漫长的运行时间之后淹没DOM解析器,例如元素树耗尽内存.

但是,在使用SAX解析器时,ContentHandler似乎限制在临时文件中累积行.这有点令人恼火,因为解析器和主应用程序可能有一个简单的协同例程关系,其中SAX解析的每一行都可以产生给应用程序.

它看起来不像以下是可能的.

def gen_rows_from_xlsx( someFile ):
    myHandler= HandlerForXLSX()
    p= xml.sax.makeParser()
    p.setContentHandler( myHandler, some_kind_of_buffer )
    for row in some_kind_of_buffer.rows():
        p.parse() # Just enough to get to the ContentHandler's "buffer.put()"
        yield row
Run Code Online (Sandbox Code Playgroud)

会定期HandlerForXLSX调用some_kind_of_buffer.put( row )将一行放入缓冲区.这一行应该通过some_kind_of_buffer.rows().

SAX解析器之间的简单协程关系gen_rows_from_xslx()将是理想的.

我是否忽略了一些生成器功能魔法,它允许我将SAX打包成某种协程?

是创建SAX解析线程并使用a Queue来获取解析器构建的行的唯一替代方法吗?

或者更容易咬住子弹并在SAX解析器中创建一个临时文件,然后通过生成器生成这些对象?

相关:带有停止/恢复的Lazy SAX XML解析器.

Joh*_*hin 5

""我有35.5Mb .XLSM文件.当实际可用内容被扩展时,它会在很长很长的运行时间之后淹没像元素树耗尽内存的DOM解析器.""

我不明白这一点.你应该使用的东西:

import xml.etree.cElementTree as ET

ET.iterparse(sourcefile) # sourcefile being a cStringIO.StringIO instance holding your worksheet XML document

element.clear() # leave only scorched earth behind you
Run Code Online (Sandbox Code Playgroud)

本文介绍如何使用iterparseclear.

示例:将XLSX(100Mb,其中大部分是两个工作表,每个包含大约16K行和大约200个col)加载到xlrd对象模型中:

经过时间约4分钟[打败旧笔记本电脑[2 GHz单核]运行Windows XP和Python 2.7].增量内存使用量最大约为300Mb内存,其中大部分是输出,而不是元素树.