Подтвердить что ты не робот

Доступ ElementTree node parent node

Я использую встроенный модуль Python ElementTree. Прямо получить доступ к детям, но как относиться к родительским или родственным узлам? - можно ли это сделать эффективно, не пройдя по всему дереву?

4b9b3361

Ответ 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())