Я использую встроенный модуль Python ElementTree. Прямо получить доступ к детям, но как относиться к родительским или родственным узлам? - можно ли это сделать эффективно, не пройдя по всему дереву?
Доступ ElementTree node parent node
Ответ 1
Нет прямой поддержки в виде атрибута parent
, но вы можете использовать описанные здесь шаблоны для достижения желаемого эффекта, Предлагается следующий однострочный (из связанного сообщения) для создания сопоставления "ребенок-родитель" для всего дерева:
parent_map = dict((c, p) for p in tree.getiterator() for c in p)
Ответ 2
ответ Vinay должен по-прежнему работать, но для Python 2.7+ и 3.2+ рекомендуется следующее:
parent_map = {c:p for p in tree.iter() for c in p}
getiterator()
устарел в пользу iter()
, и неплохо использовать новый конструктор понимания dict
.
Во-вторых, при создании XML-документа возможно, что у ребенка будет несколько родителей, хотя это будет удалено после сериализации документа. Если это имеет значение, вы можете попробовать следующее:
parent_map = {}
for p in tree.iter():
for c in p:
if c in parent_map:
parent_map[c].append(p)
# Or raise, if you don't want to allow this.
else:
parent_map[c] = [p]
# Or parent_map[c] = p if you don't want to allow this
Ответ 3
Вы можете использовать нотацию xpath ...
в ElementTree.
<parent>
<child id="123">data1</child>
</parent>
xml.findall('.//child[@id="123"]...')
>> [<Element 'parent'>]
Ответ 4
Как упоминалось в Получить родительский элемент после использования метода find (xml.etree.ElementTree), вам придется выполнять косвенный поиск родителя. Имея xml:
<a>
<b>
<c>data</c>
<d>data</d>
</b>
</a>
Предполагая, что вы создали элемент etree в переменной xml
, вы можете использовать:
In[1] parent = xml.find('.//c/..')
In[2] child = parent.find('./c')
Результат:
Out[1]: <Element 'b' at 0x00XXXXXX>
Out[2]: <Element 'c' at 0x00XXXXXX>
Более высокий родитель будет найден как: secondparent=xml.find('.//c/../..')
<Element 'a' at 0x00XXXXXX>
Ответ 5
Другой способ, если требуется только один родительский элемент subElement, а также известен путь к подэлементу subElement.
parentElement = subElement.find(xpath+"/..")
Ответ 6
Если вы используете lxml, мне удалось получить родительский элемент со следующим:
parent_node = next(child_node.iterancestors())
Ответ 7
Посмотрите на пункт 19.7.2.2. раздел: Поддерживаемый синтаксис XPath...
Найдите родителя node, используя путь:
parent_node = node.find('..')