为什么 ElementTree.iterparse 有时会不完整地检索 XML 元素?

问题描述

我正在解析一个 XML 文件,该文件太大而无法完全加载到内存中,因此我使用 xml.etree.ElementTree.iterparse 来解析它。

我遇到的问题是有时,当我从迭代器中检索一个元素时,我发现我的 XML 文件中存在的一些信息被 ElementTree 忽略。这是预期的行为吗?

一个例子

...
<car>
    <engine>
        <part name="pump"\>
        <part name="ECU"\>
    </engine>
</car>
...

假设我正在使用 xml.etree.ElementTree.iterparse 迭代器解析上面的 XML 片段。在给定的实例中,迭代器给我元素 elem,它指向 XML car 元素。

然后,我执行 xml.etree.ElementTree.dump(elem) 以查看 elem 捕获实际 XML 数据的情况,然后我得到:

<car>
    <engine>
        <part name="pump"/>
        <part/>
    </engine>
<car>

现在,注意第二个 part 元素的名称没有被捕获。为什么会发生这种情况,我该如何解决

解决方法

经过更深入的搜索,我发现人们在使用解析迭代器解析大型文档时也报告了其他 xml 解析库也存在此问题。

事实证明,当您在“开始”事件上处理元素时,该元素可能未完全加载。问题的解决方法是在“结束”事件上处理元素。

Andreas 题为 "lxml.etree iterparse() and parsing element completely" 的问题中,我借用了以下引文,我查到它来自 a tutorial on lxml

“请注意,接收开始事件时,元素的文本、尾部和子元素不一定存在。只有结束事件才能保证元素已被完全解析。”