问题描述
我正在解析一个 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:
“请注意,接收开始事件时,元素的文本、尾部和子元素不一定存在。只有结束事件才能保证元素已被完全解析。”