我使用lxml iterparse来读取巨大的xml文件。对于给定的mainElement,我检查子元素并处理每个子元素。但我注意到,在检查元素中的子节点时,解析器有时实际上会缺少一些子节点。我甚至打印了每个元素的长度,对于给定的元素标记,它应该是一个常量,但有时它比应该的要小。令人惊讶的是,这种情况通常发生在第五个块中(one block=> 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() 谢谢!
发布于 2011-11-15 06:57:03
定义上下文时,请确保将参数events设置为('end',)而不是('start',)。否则,您将获得您所描述的行为。
context=etree.iterparse(filehandle, events=('end',), tag=mainElement)我认为问题在于,lxml在一个线程中处理XML,而在另一个线程中运行parseXml,因此在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)https://stackoverflow.com/questions/8129329
复制相似问题