我使用Python的内置XML解析器来加载1.5 gig XML文件,这需要一整天。

from xml.dom import minidom
xmldoc = minidom.parse('events.xml')

我需要知道如何进入并测量其进度,以便我可以显示进度条。  任何想法?

minidom有一个名为parseString()的方法,它返回一个DOM树,假设你传递的字符串是有效的XML,如果我将文件自己拆分成块并一次一个地传递给parseString,我是否可能最后将所有DOM树合并在一起?

有帮助吗?

解决方案

你使用case要求你使用sax解析器而不是dom,dom将所有内容加载到内存中,而sax将逐行解析,你可以根据需要编写事件处理程序 所以可能有效,你也可以编写进度指标

我还建议尝试使用expat解析器,它非常有用 http://docs.python.org/library/pyexpat.html

使用sax的进度:

当sax以递增方式读取文件时,您可以使用自己的文件对象包装,并跟踪已读取的文件对象。

编辑: 我也不喜欢自己拆分文件和最后加入DOM的想法,这样你最好编写自己的xml解析器,我推荐使用sax解析器 我也想知道你在DOM树中读取1.5 gig文件的目的是什么? 看起来像萨克斯在这里会更好

其他提示

您是否考虑过使用其他解析XML的方法?构建这样一个大型XML文件的树总是很慢并且内存密集。如果您不需要内存中的整个树,基于流的解析将更快 。如果你已经习惯了基于树的XML操作,那可能会有点令人生畏,但它会以极快的速度增加(几分钟而不是几小时)。

http://docs.python.org/library/xml.sax.html

我使用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)

最后合并树很容易。您可以创建一个新的DOM,并基本上将各个树逐个附加到它。这将为您提供非常精细的控制解析进度的控制。如果您希望通过生成不同的进程来解析每个部分,您甚至可以将其并行化。你只需要确保你聪明地拆分它(不要在标签中间拆分等)。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top