2

I want to remove element but not its children. I tried with this code, but my code remove its children also.

code

import xml.etree.ElementTree as ET

tree = ET.parse('test.xml')
root = tree.getroot()

for item in root.findall('item'):
    root.remove(item)

print(ET.tostring(root))
>>> <root>
    </root>

test.xml

<?xml version="1.0" ?>
<root>
    <item>
        <data>
            <number>01</number>
            <step>one</step>
        </data>
    </item>
</root>

expected outcome

<?xml version="1.0" ?>
<root>
    <data>
        <number>01</number>
        <step>one</step>
    </data>
</root>
dtc348
  • 309
  • 6
  • 19

2 Answers2

2

You should move all children of item to root before removing

for item in root.findall('item'):
    for child in item:
        root.append(child)
    root.remove(item)

print(ET.tostring(root))

the code results in

<root>
   <data>
       <number>01</number>
       <step>one</step>
   </data>
</root>
splash58
  • 26,043
  • 3
  • 22
  • 34
0

Find the element with data tag, remove it and extend the element's parent with element's children.

import xml.etree.ElementTree as etree

data = """
<root>
    <item>
        <data>
            <number>01</number>
            <step>one</step>
        </data>
    </item>
</root>
"""

tree = etree.fromstring(data)

def iterparent(tree):
    for parent in tree.iter():
        for child in parent:
            yield parent, child

tree = etree.fromstring(data)
for parent, child in iterparent(tree):
    if child.tag == "data":
        parent.remove(child)
        parent.extend(child)

print((etree.tostring(tree)))

will output

<root>
    <item>
        <number>01</number>
        <step>one</step>
    </item>
</root>

Adapted from a similar answer for your particular use case.

mzjn
  • 48,958
  • 13
  • 128
  • 248
Ashok Arora
  • 531
  • 1
  • 6
  • 17