ProgramingTip

ElementTree 노드 부모 노드에 액세스

bestdevel 2021. 1. 7. 21:29
반응형

ElementTree 노드 부모 노드에 액세스


내장 Python ElementTree 모듈을 사용하고 있습니다. 간단하지만 부모 또는 형제 노드는 어떻습니까? -전체 트리를 사용하지 않고 수행 할 수 있습니까?


parent속성 형태의 직접적인 지원은 없지만 여기설명 된 패턴을 사용 하여 원하는 효과를 얻을 수 있습니다. 전체 트리에 대한 마이 구미-부모 매핑을 만들기 위해 다음 한 줄이 제안됩니다 (링크 된 게시물에서).

parent_map = dict((c, p) for p in tree.getiterator() for c in p)

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

...ElementTree에서 xpath 표기법을 사용할 수 있습니다 .

<parent>
     <child id="123">data1</child>
</parent>

xml.findall('.//child[@id="123"]...')
>> [<Element 'parent'>]

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>


XPath '..'선택기는 3.5.3 또는 3.6.1 (적어도 OSX에서는)에서 상위 노드를 검색하는 데 사용할 수 없습니다 (예 : 대화 형 모드).

import xml.etree.ElementTree as ET
root = ET.fromstring('<parent><child></child></parent>')
child = root.find('child')
parent = child.find('..') # retrieve the parent
parent is None # unexpected answer True

마지막 대답은 모든 희망을 깨뜨립니다 ...


단일 하위 요소의 부모를 원하고 하위 요소의 xpath도 알고 싶다면 또 다른 방법입니다.

parentElement = subElement.find(xpath+"/..")

lxml을 사용하는 경우 다음을 사용하여 부모 요소를 가져올 수 있습니다.

parent_node = next(child_node.iterancestors())

StopIteration요소에 조상이없는 경우 예외 발생하므로 해당 시나리오에 부딪 힐 수있는 경우 포착 할 준비를하십시오.


https://stackoverflow.com/a/54943960/492336 에서 내 대답을 여기에 붙여 넣으십시오 .

비슷한 문제가 있었고 약간 창의적이었습니다. 우리가 친자 관계 정보를 직접 추가하는 것을 방해하는 것은 없습니다. 더 이상 필요하지 않으면 나중에 제거 할 수 있습니다.

def addParentInfo(et):
    for child in et:
        child.attrib['__my_parent__'] = et
        addParentInfo(child)

def stripParentInfo(et):
    for child in et:
        child.attrib.pop('__my_parent__', 'None')
        stripParentInfo(child)

def getParent(et):
    if '__my_parent__' in et.attrib:
        return et.attrib['__my_parent__']
    else:
        return None

# Example usage

tree = ...
addParentInfo(tree.getroot())
el = tree.findall(...)[0]
parent = getParent(el)
while parent:
    doSomethingWith(parent)
    parent = getParent(parent)
stripParentInfo(tree.getroot())

19.7.2.2를보십시오. 섹션 : 지원되는 XPath 구문 ...

경로를 사용하여 노드의 부모를 찾습니다.

parent_node = node.find('..')

참조 URL : https://stackoverflow.com/questions/2170610/access-elementtree-node-parent-node

반응형