如何使用 python 将 XML 文件中的节点拆分为两个节点

how to split a node in a XML file into two nodes using python

假设我有一个这样的 XML 文件:

<?xml version="1.0"?>
<data>
    <group>
        <country name="Liechtenstein">
            <rank>1</rank>
            <year>2008</year>
        </country>
        <country name="Singapore">
            <rank>4</rank>
            <year>2011</year>
        </country>
        <country name="Panama">
            <rank>68</rank>
            <year>2011</year>
        </country>
    </group>
</data>

而我想在"Singapore"之后将"group"的节点一分为二,如:

<?xml version="1.0"?>
<data>
    <group>
        <country name="Liechtenstein">
            <rank>1</rank>
            <year>2008</year>
        </country>
        <country name="Singapore">
            <rank>4</rank>
            <year>2011</year>
        </country>
    </group>
    <group>
        <country name="Panama">
            <rank>68</rank>
            <year>2011</year>
        </country>
    </group>
</data>

是否可以使用 python 中的 ElementTree 来做到这一点?

非常感谢。

是的,你可以,但是使用 lxml 库更容易:

from lxml import etree

content = u"""\
<data>
    <group>
        <country name="Liechtenstein">
            <rank>1</rank>
            <year>2008</year>
        </country>
        <country name="Singapore">
            <rank>4</rank>
            <year>2011</year>
        </country>
        <country name="Panama">
            <rank>68</rank>
            <year>2011</year>
        </country>
    </group>
</data>"""

root = etree.XML(content)

# insert a new "<group>" element at the end of "<data>" children:
new_group = etree.SubElement(root, "group")

# find "Panama"
panama = root.xpath('//country[@name="Panama"]')[0]

# move "Panama" into the new group
new_group.append(panama)

您将获得:

<data>
    <group>
        <country name="Liechtenstein">
            <rank>1</rank>
            <year>2008</year>
        </country>
        <country name="Singapore">
            <rank>4</rank>
            <year>2011</year>
        </country>
        </group>
<group><country name="Panama">
            <rank>68</rank>
            <year>2011</year>
        </country>
    </group></data>

编辑

查找"Singapore"

之后的所有国家
other_nodes = root.xpath('//country[count(preceding-sibling::country[@name = "Singapore"]) != 0]')

将找到的节点移动到新组中

new_group.extend(other_nodes)

您可以尝试遍历每个节点,然后将名称为 Panama 的节点存储到一个临时变量中,并创建一个新的 Element 并添加到根树中。

import xml.etree.ElementTree as ET

items = """
<data>
    <group>
        <country name="Liechtenstein">
            <rank>1</rank>
            <year>2008</year>
        </country>
        <country name="Singapore">
            <rank>4</rank>
            <year>2011</year>
        </country>
        <country name="Panama">
            <rank>68</rank>
            <year>2011</year>
        </country>
    </group>
</data>
"""

root = ET.fromstring(items)
node_panama = None
for group in root:
    for country in group.findall('country'):
        name = country.attrib['name']
        if name == 'Panama':
            node_panama = country
            group.remove(country)

new_group = ET.Element('group')
new_group.append(node_panama)

root.append(new_group)
ET.dump(root)

哪个会输出

<data>
    <group>
        <country name="Liechtenstein">
            <rank>1</rank>
            <year>2008</year>
        </country>
        <country name="Singapore">
            <rank>4</rank>
            <year>2011</year>
        </country>
    </group>
    <group>
        <country name="Panama">
            <rank>68</rank>
            <year>2011</year>
        </country>
    </group>
</data>