Python 使用 xml iterparse 从大型 xml 文件中删除元素

Python removing elements from large xml file with xml iterparse

我是 Python 的新手,最近一直在使用它来尝试解析一个 700mb 的大 xml 文件。

环顾四周,我一直在尝试使用 iterparse 方法为 XML 删除名为 Revision_History 的元素,因为我们不再需要此信息。

我已经对这个脚本进行了一些修改,所以现在它可能错得离谱。对于前两次删除,它似乎工作正常。但是它随后停止工作并且找不到更多 revision_history 标签。

import xml.etree.ElementTree as ET
for event, elem in ET.iterparse("AAT.xml", events=("end",)):
if event == "end":
     for subject in elem.findall ("{http://localhost/namespace}Subject"):
        print ("subject found")
        for revision in subject.findall("("{http://localhost/namespace}Revision_History"):
            print ("revision found")
            subject.remove (revision)
            print ("done")
    elem.clear()

非常感谢任何建议!

亚当

尝试使用 cElementTree 而不是 ElementTree。对我来说显着快了,但我从来没有解析过你正在解析的大小的文件

from xml.etree import cElementTree as ET

其次,尝试在匹配元素上使用 iterfind() 而不是 findall()

from xml.etree import cElementTree as ET

for event, elem in ET.iterparse("books.xml", events=("end",)):
    if elem.tag == "book":
        for d in elem.iterfind("description"):
            elem.remove(d)

第三,根据您要使用的 RAM 大小,您可以尝试使用 XPath 查找具有您要删除的 child 的元素。然后,遍历parents,删除那些children。非常糟糕的例子:

for event, elem in ET.iterparse("books.xml", events=("end",)):
    for book_with_desc in elem.iterfind(".//Subject[Revision_History]"):
        for child in book_with_desc:
            if child.tag == "Revision_History":
                remove(child)

使用 XPath,如果您知道文档的结构,请尽量避免使用 .//foo 路径,并编写更高效的查询,例如 ./path/to/element/foo[@attr=bar] 或类似的。

我相信有很多更好的方法可以解决这个问题。