我正在使用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()
谢谢!
答案 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)