Как получить все подэлементы дерева элементов с помощью Python ElementTree?

Я хочу найти способ получить все подэлементы дерева элементов, как это делает ElementTree.getchildren(), поскольку getchildren() устарел, начиная с Python версии 2.7.
Я больше не хочу его использовать, хотя все еще могу используйте его в настоящее время.


person j5shi    schedule 02.05.2012    source источник


Ответы (5)


Все подэлементы (потомки) elem:

all_descendants = list(elem.iter())

Более полный пример:

>>> import xml.etree.ElementTree as ET
>>> a = ET.Element('a')
>>> b = ET.SubElement(a, 'b')
>>> c = ET.SubElement(a, 'c')
>>> d = ET.SubElement(a, 'd')
>>> e = ET.SubElement(b, 'e')
>>> f = ET.SubElement(d, 'f')
>>> g = ET.SubElement(d, 'g')
>>> [elem.tag for elem in a.iter()]
['a', 'b', 'e', 'c', 'd', 'f', 'g']

Чтобы исключить сам корень:

>>> [elem.tag for elem in a.iter() if elem is not a]
['b', 'e', 'c', 'd', 'f', 'g']
person Eli Bendersky    schedule 02.05.2012
comment
Извини Эли, но может я не так выразился, я просто хочу получить все подэлементы, а не еще и рут. то есть корень здесь нежелателен. но я думаю, что ваш метод также содержит корневой объект, верно? - person j5shi; 02.05.2012
comment
Но что, если существует более одной структуры с тегом «а», вложенной в элемент «а», и я хочу получить все подэлементы всех структур «а»? - person j5shi; 02.05.2012
comment
Объекты элементов могут повторяться и без использования iter(). Элемент также ведет себя как список; поэтому вы также можете индексировать подэлементы. - person pepr; 02.05.2012
comment
@pepr: да, но это дает вам только непосредственных дочерних элементов элемента, а не всех потомков - person Eli Bendersky; 02.05.2012
comment
@Эли Бендерски: Понятно. Но getchildren() также возвращает только непосредственных потомков. Старым эквивалентом нового list(elem.iter()) является list(elem.getiterator()). Это зависит от того, чего на самом деле хочет Стивен. - person pepr; 02.05.2012

в pydoc упоминается использование метода list() над узлом для получения дочерних элементов.
list(elem)

person Harshal Zope    schedule 22.08.2018
comment
list() уже было предложено в предыдущих ответах, а также в ответе, помеченном как правильный. В этом ответе не было особой необходимости. - person Goran Kutlaca; 22.08.2018
comment
@GoranKutlaca: проверь мой ответ. в нем говорится, что использовать list(elem) не использовать list(elem.iter()). В обоих звонках есть разница. list(elem) даст только подэлементы. - person Harshal Zope; 27.08.2018
comment
Это то, что я искал ... вопрос, к сожалению, немного двусмысленный, хотя ссылка на детей, а не на всех потомков, предполагает, что это то, чего хотел и ОП. - person mike rodent; 16.04.2021

Если вы хотите получить все элементы «a», вы можете использовать:

a_lst = list(elem.iter('a'))

Если elem также является 'a', он будет включен.

person pepr    schedule 02.05.2012

Возможно, это не соответствует фактическому вопросу OP, но в более широком смысле я бы предположил, что если кто-то хочет, чтобы все элементы были названы определенным именем, например. 'object' может использовать (альтернативный подход к @Turtles Are Cute, который мне, по крайней мере, кажется более естественным):

objs = tree.findall('object')

который также возвращает список.

person Eypros    schedule 24.08.2018

Ни один из существующих ответов не найдет всех детей. Это решение использует BeautifulSoup вместо ETree, но найдет все дочерние элементы, а не только верхний уровень:

from bs4 import BeautifulSoup    

with open(filename) as f:
    soup = BeautifulSoup(f, 'xml')

results = soup.find_all('element_name')
person Turtles Are Cute    schedule 02.03.2017