当前位置: 首页 > 工具软件 > 123Tree > 使用案例 >

python elementtree 父节点_python-访问ElementTree节点父节点

赵晨
2023-12-01

python-访问ElementTree节点父节点

我正在使用内置的Python ElementTree模块。 访问子级很简单,但是父级或同级节点呢? -是否可以有效地完成而不遍历整个树?

hoju asked 2019-12-30T00:32:30Z

9个解决方案

44 votes

没有parent属性形式的直接支持,但是您也许可以使用此处描述的模式来实现所需的效果。 建议使用以下单行代码(从链接到文章)为整个树创建子到父映射:

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

Vinay Sajip answered 2019-12-30T00:32:49Z

20 votes

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

supergra answered 2019-12-30T00:33:18Z

10 votes

您可以在ElementTree中使用xpath ...表示法。

data1

xml.findall('.//child[@id="123"]...')

>> []

josven answered 2019-12-30T00:33:38Z

5 votes

如使用查找方法(xml.etree.ElementTree)后获取父元素中所述,您将不得不间接搜索父对象。具有xml:

data

data

假设您已将etree元素创建为secondparent=xml.find('.//c/../..')变量,则可以使用:

In[1] parent = xml.find('.//c/..')

In[2] child = parent.find('./c')

导致:

Out[1]:

Out[2]:

高级父母将被发现为:secondparent=xml.find('.//c/../..')是

Vaasha answered 2019-12-30T00:34:11Z

3 votes

XPath'..'选择器不能用于在3.5.3或3.6.1(至少在OSX上)上检索父节点,例如在交互模式下:

import xml.etree.ElementTree as ET

root = ET.fromstring('')

child = root.find('child')

parent = child.find('..') # retrieve the parent

parent is None # unexpected answer True

最后一个答案打破了所有希望。

jlaurens answered 2019-12-30T00:34:36Z

2 votes

如果只想要一个subElement的父级,并且也知道subElement的xpath,则是另一种方式。

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

MK at Soho answered 2019-12-30T00:34:55Z

1 votes

如果您使用的是lxml,则可以使用以下命令获取父元素:

parent_node = next(child_node.iterancestors())

如果元素没有祖先,则将引发StopIteration异常-因此,如果您可能遇到这种情况,请准备好捕获该异常。

Shadow answered 2019-12-30T00:35:20Z

1 votes

将我的答案从[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())

sashoalm answered 2019-12-30T00:35:45Z

-1 votes

看一下19.7.2.2。 部分:支持的XPath语法...

使用以下路径查找节点的父节点:

parent_node = node.find('..')

Alf answered 2019-12-30T00:36:09Z

 类似资料: