在 Python 中,如何使用 xml.etree
API 删除节点但保留其子节点?
是的,我知道有一个 answer using lxml但由于 xml.etree
是 Python 网站的一部分,我认为它也值得一个答案。
原始 xml 文件:
<?xml version="1.0"?>
<data>
<country name="Liechtenstein">
<rank>1</rank>
<year>2008</year>
<gdppc>141100</gdppc>
<neighbor name="Austria" direction="E"/>
<neighbor name="Switzerland" direction="W"/>
</country>
<country name="Singapore">
<rank>4</rank>
<year>2011</year>
<gdppc>59900</gdppc>
<neighbor name="Malaysia" direction="N"/>
</country>
<country name="Panama">
<rank>68</rank>
<year>2011</year>
<gdppc>13600</gdppc>
<neighbor name="Costa Rica" direction="W"/>
<neighbor name="Colombia" direction="E"/>
</country>
</data>
假设我想删除 country
节点,但保留子节点并将它们分配给 country
的父节点?
理想情况下,我想要一个“就地”执行操作而不是创建新树的解决方案。
我的(非工作)解决方案:
# Get all parents of `country`
for country_parent in root.findall(".//country/.."):
print(country_parent.tag)
# Some countries could have same parent so get all
# `country` nodes of current parent
for country in country_parent.findall("./country"):
print('\t', country.tag)
# For each child of `country`, assign it to parent
# and then delete it from `parent`
for country_child in country:
print('\t\t', country_child.tag)
country_parent.append(country_child)
country.remove(country_child)
country_parent.remove(country)
tree.write("test_mod.xml")
我的打印语句的输出:
data
country
rank
gdppc
neighbor
country
rank
gdppc
country
rank
gdppc
neighbor
我们马上就可以看到有一个问题:country
缺少标签year
和一些neighbor
标签。
生成的.xml
输出:
<data>
<rank>1</rank>
<gdppc>141100</gdppc>
<neighbor direction="W" name="Switzerland" />
<rank>4</rank>
<gdppc>59900</gdppc>
<rank>68</rank>
<gdppc>13600</gdppc>
<neighbor direction="E" name="Colombia" />
</data>
这显然是错误的。
问题:为什么会发生这种情况?
我可以想象这是由于附加/删除破坏了列表中的某些内容,即我已经使列表“无效”,类似于迭代器。
最佳答案
从程序中删除此行:
country.remove(country_child)
xml.etree.ElementTree.Element
的迭代本质上是传递给子元素的list
。在迭代期间修改该列表将产生奇怪的结果。
关于python xml.etree - 删除节点但保留子节点(将子节点分配给祖 parent ),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38021298/