Home > database >  Deleting xml node from tree based on element criteria
Deleting xml node from tree based on element criteria

Time:01-29

I'm working with XMLs and I'm trying to delete <node> based on element's criteria. The idea is to delete 2nd ITEM. I tried to make list of ITEMS and then based on that list removed them from root lvl but I got

ValueError "ValueError: list.remove(x): x not in list"

and I have no idea how to get to higher lvl.

Code:

import xml.etree.ElementTree as ET

tree = ET.parse("PW.xml")
root = tree.getroot()

items = root.findall('.//ITEM[PROPERTY]')
m = -1
delate = []
for i in items:
  pl = i.findall('PROPERTY[@NAME="ID detalu"]')
  #print([(pv.attrib['NAME'], pv.text) for pv in pl])
  m = m   1
  for p in pl:
    if (p.text.startswith('SHP')):
      delate.append(m) 

tree.write('PW.xml')

XML:

<DATA>
    <OBJECT TYPE="Dane">
        <ITEM>
            <PROPERTY NAME="[1]" />
            <PROPERTY NAME="child2">0\557</PROPERTY>
            <PROPERTY NAME="child3">MNO001366</PROPERTY>
            <PROPERTY NAME="child4">1507</PROPERTY>
            <PROPERTY NAME="child5" />
            <PROPERTY NAME="child6" />
            <PROPERTY NAME="ID detalu">PL.10.000033</PROPERTY>
        </ITEM>
        <ITEM>
            <PROPERTY NAME="[1]" />
            <PROPERTY NAME="child2">0\557</PROPERTY>
            <PROPERTY NAME="child3">MNO001485</PROPERTY>
            <PROPERTY NAME="child4">1626</PROPERTY>
            <PROPERTY NAME="child5" />
            <PROPERTY NAME="child6">Pintos</PROPERTY>
            <PROPERTY NAME="ID detalu">SHP001432</PROPERTY>
         </ITEM>
    </OBJECT>
</DATA>

CodePudding user response:

I cannot reproduce the error message. Anyway, to remove an element, you need to have a reference to its parent, so that you can do parent.remove(child). The parent of the ITEM elements is OBJECT.

Here is a demo:

import xml.etree.ElementTree as ET
 
tree = ET.parse("PW.xml")
root = tree.getroot()
 
to_delete = []
 
object = root.find("OBJECT")
 
items = root.findall(".//ITEM")
 
# Find the items to delete and add them to the to_delete list
for item in items:
    prop = item.find("PROPERTY[@NAME='ID detalu']")
    if prop is not None and prop.text.startswith("SHP"):
        to_delete.append(item)
 
# Do the actual deletion of items
for item in to_delete:
    object.remove(item)
 
print(ET.tostring(root).decode())

Output:

<DATA>
    <OBJECT TYPE="Dane">
        <ITEM>
            <PROPERTY NAME="[1]" />
            <PROPERTY NAME="child2">0\557</PROPERTY>
            <PROPERTY NAME="child3">MNO001366</PROPERTY>
            <PROPERTY NAME="child4">1507</PROPERTY>
            <PROPERTY NAME="child5" />
            <PROPERTY NAME="child6" />
            <PROPERTY NAME="ID detalu">PL.10.000033</PROPERTY>
        </ITEM>
        </OBJECT>
</DATA>
  •  Tags:  
  • Related