lxml iterparse mising子节点

时间:2011-11-14 22:49:02

标签: python lxml

我正在使用lxml iterparse来读取巨大的xml文件。对于给定的mainElement,我检查子元素并处理每个子元素。但是我注意到,在检查元素中的子节点时,解析器实际上有时会丢失一些子节点。我甚至打印了每个元素的长度,对于给定的元素标记,它应该是一个常数,但它有时会小于应有的值。而且令人惊讶的是,这通常发生在第5个块(一个块=> mainElement出现)。解析器是否应该错过子节点?有线索吗?

示例代码 -

from lxml import etree  
def parseXml(context,attribList,elemList,mainElement):      
   for event, element in context: 
       if element.tag == mainElement and event=='start':
            for child in element:
               if child.tag in elemList:
                   print len(child) #for a given child,the len should be constant
                   #do things   
       elif event=='end':
         element.clear() 

谢谢!

1 个答案:

答案 0 :(得分:2)

定义上下文时,请务必将参数events设置为('end',)而不是('start',)。否则,您可以获得您描述的行为。

context=etree.iterparse(filehandle, events=('end',), tag=mainElement)

我认为问题是lxml在另一个线程中运行parseXml时在一个线程中处理XML,因此在lxml完成​​解析之前,您可以在start中找到parseXml元素相应的end元素。因此,当您遍历元素的子元素时,只会获得部分结果。


顺便说一句,this article提供了一种很好的组织方式,用于处理非常大的XML:

def fast_iter(context, func, *args, **kwargs):
    # http://www.ibm.com/developerworks/xml/library/x-hiperfparse/
    # Author: Liza Daly
    for event, elem in context:
        func(elem, *args, **kwargs)
        elem.clear()
        while elem.getprevious() is not None:
            del elem.getparent()[0]
    del context

def parseXml(element,attribList,elemList): 
    for child in element:
       if child.tag in elemList:
           print len(child) #for a given child,the len should be constant
           #do things   

context=etree.iterparse(filehandle, events=('end',), tag=mainElement)   
fast_iter(context, parseXml, attribList, elemList)