I have an XML document in which I want to search for some elements and if they match some criteria I would like to delete them
However, I cannot seem to be able to access the parent of the element so that I can delete it
file = open('test.xml', "r") elem = ElementTree.parse(file) namespace = "{http://somens}" props = elem.findall('.//{0}prop'.format(namespace)) for prop in props: type = prop.attrib.get('type', None) if type == 'json': value = json.loads(prop.attrib['value']) if value['name'] == 'Page1.Button1': #here I need to access the parent of prop # in order to delete the prop
Is there a way I can do this?
Thanks
You can remove child elements with the according remove
method. To remove an element you have to call its parents remove
method. Unfortunately Element
does not provide a reference to its parents, so it is up to you to keep track of parent/child relations (which speaks against your use of elem.findall()
)
A proposed solution could look like this:
root = elem.getroot() for child in root: if child.name != "prop": continue if True:# TODO: do your check here! root.remove(child)
PS: don't use prop.attrib.get()
, use prop.get()
, as explained here.
You could use xpath to select an Element's parent.
file = open('test.xml', "r") elem = ElementTree.parse(file) namespace = "{http://somens}" props = elem.findall('.//{0}prop'.format(namespace)) for prop in props: type = prop.get('type', None) if type == 'json': value = json.loads(prop.attrib['value']) if value['name'] == 'Page1.Button1': # Get parent and remove this prop parent = prop.find("..") parent.remove(prop)
http://docs.python.org/2/library/xml.etree.elementtree.html#supported-xpath-syntax
Except if you try that it doesn't work: http://elmpowered.skawaii.net/?p=74
So instead you have to:
file = open('test.xml', "r") elem = ElementTree.parse(file) namespace = "{http://somens}" search = './/{0}prop'.format(namespace) # Use xpath to get all parents of props prop_parents = elem.findall(search + '/..') for parent in prop_parents: # Still have to find and iterate through child props for prop in parent.findall(search): type = prop.get('type', None) if type == 'json': value = json.loads(prop.attrib['value']) if value['name'] == 'Page1.Button1': parent.remove(prop)
It is two searches and a nested loop. The inner search is only on Elements known to contain props as first children, but that may not mean much depending on your schema.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With