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

时间:2015-02-10 10:28:54

标签: python xml elementtree

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

环顾四周后,我一直在尝试使用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()

任何建议都非常感谢!

亚当

1 个答案:

答案 0 :(得分:1)

尝试使用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查找包含您要删除的子项的元素。然后,遍历父母,删除这些孩子。非常糟糕的例子:

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]或类似的。

有很多更好的方法可以解决这个问题,我确定。