代码之家  ›  专栏  ›  技术社区  ›  Nathan

显示加载大型文件时python的XML解析器的进度

  •  2
  • Nathan  · 技术社区  · 15 年前

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

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

    我需要知道如何进入它并测量它的进度,这样我才能显示进度条。 有什么想法吗?

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

    4 回复  |  直到 14 年前
        1
  •  5
  •   Benjamin Wohlwend    15 年前

    您是否考虑使用其他解析XML的方法?构建一个包含如此大的XML文件的树总是很慢而且占用大量内存。如果在内存中不需要整个树,那么基于流的解析将非常有用 更快。如果您习惯于基于树的XML操作,这可能会有点让人望而生畏,但它会带来巨大的速度提升(几分钟而不是几小时)。

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

        2
  •  5
  •   Anurag Uniyal    15 年前

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

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

    有关使用sax的进度:

    编辑: 我还想知道您在DOM树中读取1.5Gig文件的目的是什么? 看起来萨克斯在这里会更好

        3
  •  3
  •   eduffy    15 年前

    我使用pulldomapi为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)
    
        4
  •  2
  •   Dan Lorenc    15 年前

    在末尾合并树将非常容易。您可以创建一个新的DOM,并基本上将各个树逐个附加到其中。这将使您能够对解析的进度进行非常精细的控制。如果需要的话,您甚至可以通过生成不同的进程来解析每个部分来并行化它。你只需要确保你智能地分割它(不在标签中间分裂)等等。