我使用内建的Python ElementTree的模块。是简单的儿童获得,但对于父母或兄弟节点? - ?可以这样无需遍历整个树有效地完成

有帮助吗?

解决方案

有是在一个parent属性的形式没有直接的支持,但可以或许使用模式中描述的此处以实现期望的效果。以下单行建议(从链接到后),以创建一个子到父映射为一整棵树:

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

其他提示

应该仍然工作,但为Python 2.7+ 3.2+及以下推荐的Vinay的答案

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

可以使用XPath ...符号的ElementTree。

<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('..')
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top