python xml.etree - 删除节点但保留子节点(将子节点分配给祖 parent )

标签 python xml xml-parsing

在 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/

相关文章:

c# - 如何在 Windows 窗体应用程序中保存应用程序设置?

iphone - NSXMLParserDelegate 方法未被调用

python - 用于监视服务器运行状况的脚本库?

Python 正则表达式向后看

python - Python中通过一列的特定总和值选择前N行

xml - 如何防止 JSON Web 服务响应下载到文件?

java - 如何查找另一个标签之前最后一次出现的 XML 标签

python - 我可以在保留 lambda 表达式的同时删除双重评估吗

python - 高效 XML 解析 25GB 数据

java - 使用 Java 从 XML 文件获取属性