我使用Python的内置XML解析器来加载1.5 gig XML文件,这需要一整天。
from xml.dom import minidom
xmldoc = minidom.parse('events.xml')
我需要知道如何进入并测量其进度,以便我可以显示进度条。 任何想法?
minidom有一个名为parseString()的方法,它返回一个DOM树,假设你传递的字符串是有效的XML,如果我将文件自己拆分成块并一次一个地传递给parseString,我是否可能最后将所有DOM树合并在一起?
答案 0 :(得分:5)
您是否考虑过使用其他解析XML的方法?构建这样一个大型XML文件的树总是很慢并且内存密集。如果您不需要内存中的整个树,基于流的解析将更快 。如果你已经习惯了基于树的XML操作,那可能会有点令人生畏,但它会以极快的速度增加(几分钟而不是几小时)。
答案 1 :(得分:5)
你使用case要求你使用sax解析器而不是dom,dom将所有内容加载到内存中,而sax将逐行解析,你可以根据需要编写事件处理程序 所以可能有效,你也可以编写进度指标
我还建议尝试使用expat解析器,它非常有用 http://docs.python.org/library/pyexpat.html
使用sax的进度:
当sax以递增方式读取文件时,您可以使用自己的文件对象包装,并跟踪已读取的文件对象。
编辑: 我也不喜欢自己拆分文件和最后加入DOM的想法,这样你最好编写自己的xml解析器,我推荐使用sax解析器 我也想知道你在DOM树中读取1.5 gig文件的目的是什么? 看起来像萨克斯在这里会更好
答案 2 :(得分:3)
我使用pulldom api对PyGTK有一些非常相似的东西,而不是PyQt。它使用Gtk空闲事件(因此GUI不会锁定)和Python生成器(以保存解析状态)一次调用一次。
def idle_handler (fn):
fh = open (fn) # file handle
doc = xml.dom.pulldom.parse (fh)
fsize = os.stat (fn)[stat.ST_SIZE]
position = 0
for event, node in doc:
if position != fh.tell ():
position = fh.tell ()
# update status: position * 100 / fsize
if event == ....
yield True # idle handler stays until False is returned
yield False
def main:
add_idle_handler (idle_handler, filename)
答案 3 :(得分:2)
最后合并树很容易。您可以创建一个新的DOM,并基本上将各个树逐个附加到它。这将为您提供非常精细的控制解析进度的控制。如果您希望通过生成不同的进程来解析每个部分,您甚至可以将其并行化。你只需要确保你聪明地拆分它(不要在标签中间拆分等)。