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]
或类似的。
我相信有很多更好的方法可以解决这个问题。
我是 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]
或类似的。
我相信有很多更好的方法可以解决这个问题。