使用ElementTree跟踪父元素 [英] Keep track of parent elements using ElementTree
问题描述
这是我的XML:
<beans>
<property name = "type1">
<list>
<bean class = "bean1">
<property name = "typeb">
<value>foo</value>
</property>
</bean>
<bean class = "bean2">
<property name ="typeb">
<value>bar</value>
</property>
</bean>
</list>
</property>
<property name = "type2">
<list>
<bean class = "bean3">
<list>
<property name= "typec">
<sometags/>
</property>
<property name= "typed">
<list>
<value>foo</value>
<value>bar</bar>
</list>
</property>
</list>
</bean>
</list>
</property>
</beans>
现在我们要做的就是扫描并删除以下元素:
Now what we're want to do is scan through this and delete these elements:
<bean class = "bean1">
<property = "typeb">
<value>foo</value>
</property>
</bean>
并且:
<value>foo</value>
(来自属性类= typed元素)。
(from the property class = "typed" element).
现在要实现这一目标,我想做的就是这样:
Now to achieve this, what I'd like to do is something like this:
for element in root.iter('value'):
if element.text == 'foo':
p1= element.getParent()
if p1.tag == 'list': #second case scenario, remove just the value tag.
p1.remove(element)
else: #first case scenario - remove entire bean
p2 = p1.getParent()
p3 = p2.getParent()
p3.remove(p2)
但是 ElementTree
不支持孩子看到其父元素。
However ElementTree
doesn't support an child seeing its parent element.
实现此目标的有效方法是什么?鉴于它是一个深层的XML结构,我不太喜欢使用递归函数在每个级别检查标记类型的想法。
What would an effective way to achieve this be? Given that it is a deep XML structure, I don't quite like the idea of a recursive function that checks the tag types at each level.
推荐答案
这是我的解决方法:
#gives you a list of every parent,child tuple
def iterparent(tree):
for parent in tree.getiterator():
for child in parent:
yield parent, child
#recursive function. Deletes the given child node, from n parents back.
#If n = 0 it deletes just the child.
def removeParent(root, childToRemove, n):
for parent, child in iterparent(root):
if (childToRemove == child):
if n>0:
removeParent(root, parent, n-1)
else:
parent.remove(child)
for parent, child in iterparent(root):
if (child.tag == 'value' and (child.text in valuesToDelete):
if (parent.tag == 'list'):
removeParent(root, child, 0)
else:
removeParent(root, child, 2)
实际上非常优雅,我喜欢它。
It's actually quite elegant. I like it.
就我的目的而言,这很好用,但是可能难以适应各种各样的元素结构和深度。
For my purposes, this works well, but one might have difficulty with a wide range of element structures and depths.
这篇关于使用ElementTree跟踪父元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!