Lat*_*der 8 python xml elementtree
我需要解析一个非常大的(~40GB)XML文件,从中删除某些元素,并将结果写入新的xml文件.我一直在尝试使用python的ElementTree中的iterparse,但我对如何修改树然后将结果树写入新的XML文件感到困惑.我已经阅读了关于itertree的文档,但它还没有解决问题.有没有简单的方法来做到这一点?
谢谢!
编辑:这是我到目前为止所拥有的.
import xml.etree.ElementTree as ET
import re
date_pages = []
f=open('dates_texts.xml', 'w+')
tree = ET.iterparse("sample.xml")
for i, element in tree:
if element.tag == 'page':
for page_element in element:
if page_element.tag == 'revision':
for revision_element in page_element:
if revision_element.tag == '{text':
if len(re.findall('20\d\d', revision_element.text.encode('utf8'))) == 0:
element.clear()
Run Code Online (Sandbox Code Playgroud)
如果你有一个不适合内存的大型xml,那么你可以尝试一次序列化一个元素.例如,假设<root><page/><page/><page/>...</root>
文档结构并忽略可能的命名空间问题:
import xml.etree.cElementTree as etree
def getelements(filename_or_file, tag):
context = iter(etree.iterparse(filename_or_file, events=('start', 'end')))
_, root = next(context) # get root element
for event, elem in context:
if event == 'end' and elem.tag == tag:
yield elem
root.clear() # free memory
with open('output.xml', 'wb') as file:
# start root
file.write(b'<root>')
for page in getelements('sample.xml', 'page'):
if keep(page):
file.write(etree.tostring(page, encoding='utf-8'))
# close root
file.write(b'</root>')
Run Code Online (Sandbox Code Playgroud)
如果应该保留keep(page)
返回的地方,例如:True
page
import re
def keep(page):
# all <revision> elements must have 20xx in them
return all(re.search(r'20\d\d', rev.text)
for rev in page.iterfind('revision'))
Run Code Online (Sandbox Code Playgroud)
为了进行比较,要修改一个小的 xml文件,您可以:
# parse small xml
tree = etree.parse('sample.xml')
# remove some root/page elements from xml
root = tree.getroot()
for page in root.findall('page'):
if not keep(page):
root.remove(page) # modify inplace
# write to a file modified xml tree
tree.write('output.xml', encoding='utf-8')
Run Code Online (Sandbox Code Playgroud)
也许我的类似问题的答案可以帮助你。
至于如何将其写回 .xml 文件,我最终在脚本的底部执行了此操作:
with open('File.xml', 'w') as t: # I'd suggest using a different file name here than your original
for line in ET.tostring(doc):
t.write(line)
t.close
print('File.xml Complete') # Console message that file wrote successfully, can be omitted
Run Code Online (Sandbox Code Playgroud)
该变量doc
来自我的脚本中较早的部分,与您的位置相当,tree = ET.iterparse("sample.xml")
我有这个:
doc = ET.parse(filename)
Run Code Online (Sandbox Code Playgroud)
我一直在使用 lxml 而不是 ElementTree,但我认为写出部分应该仍然可以工作(我认为这主要只是 ElementTree 无法处理的 xpath 内容。)我正在使用通过这一行导入的 lxml:
from lxml import etree as ET
Run Code Online (Sandbox Code Playgroud)
希望这(以及我的链接问题,如果您需要一些额外的代码上下文)可以帮助您!