Как упоминалось в ответе Кевина Герры, стратегия «root.clear()» в документации ElementTree удаляет только полностью проанализированные дочерние элементы корня. Если эти дети привязывают огромные ветки, это не очень полезно.
Он коснулся идеального решения, но не опубликовал никакого кода, поэтому вот пример:
element_stack = []
context = ET.iterparse(stream, events=('start', 'end'))
for event, elem in context:
if event == 'start':
element_stack.append(elem)
elif event == 'end':
element_stack.pop()
# see if elem is one of interest and do something with it here
if element_stack:
element_stack[-1].remove(elem)
del context
Интересующий элемент не будет иметь подэлементов; они будут удалены, как только будут видны их конечные теги. Это может быть нормально, если все, что вам нужно, это текст или атрибуты элемента.
Если вы хотите запросить потомков элемента, вам нужно позволить построить для него полную ветвь. Для этого поддерживайте флаг, реализованный как счетчик глубины для этих элементов. Вызывайте .remove() только тогда, когда глубина равна нулю:
element_stack = []
interesting_element_depth = 0
context = ET.iterparse(stream, events=('start', 'end'))
for event, elem in context:
if event == 'start':
element_stack.append(elem)
if elem.tag == 'foo':
interesting_element_depth += 1
elif event == 'end':
element_stack.pop()
if elem.tag == 'foo':
interesting_element_depth -= 1
# do something with elem and its descendants here
if element_stack and not interesting_element_depth:
element_stack[-1].remove(elem)
del context
person
Mike Brown
schedule
12.06.2017