使用lxml和iterparse()解析大(+-1Gb)XML文件


问题内容

我必须解析具有如下结构的1Gb XML文件,并在标签“作者”和“内容”中提取文本:

<Database>
    <BlogPost>
        <Date>MM/DD/YY</Date>
        <Author>Last Name, Name</Author>
        <Content>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas dictum dictum vehicula.</Content>
    </BlogPost>

    <BlogPost>
        <Date>MM/DD/YY</Date>
        <Author>Last Name, Name</Author>
        <Content>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas dictum dictum vehicula.</Content>
    </BlogPost>

    [...]

    <BlogPost>
        <Date>MM/DD/YY</Date>
        <Author>Last Name, Name</Author>
        <Content>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas dictum dictum vehicula.</Content>
    </BlogPost>
</Database>

到目前为止,我已经尝试了两件事:i)读取整个文件并使用.find(xmltag)进行遍历,并且ii)使用lxml和iterparse()解析xml文件。第一种选择是使它工作,但速度很慢。第二种选择我还没有成功。

这是我所拥有的一部分:

for event, element in etree.iterparse(path_to_file, tag="BlogPost"):
    if element.tag == "BlogPost":
        print element.text
    else:
        print 'Finished'

其结果是只有空格,没有文本。

我一定做错了,但我无法把握。另外,如果还不够明显,我是python的新手,这是我第一次使用lxml。请帮忙!


问题答案:
for event, element in etree.iterparse(path_to_file, tag="BlogPost"):
    for child in element:
        print child.tag, child.text
    element.clear()

最后的清除将阻止您使用过多的内存。

[更新:]要获得“…之间的所有信息,作为字符串”,我想您需要以下其中一项:

for event, element in etree.iterparse(path_to_file, tag="BlogPost"):
    print etree.tostring(element)
    element.clear()

要么

for event, element in etree.iterparse(path_to_file, tag="BlogPost"):
    print ''.join([etree.tostring(child) for child in element])
    element.clear()

甚至:

for event, element in etree.iterparse(path_to_file, tag="BlogPost"):
    print ''.join([child.text for child in element])
    element.clear()