Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Search and remove element with elementTree in Python

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

like image 677
Thomas Avatar asked Jul 27 '11 15:07

Thomas


2 Answers

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.

like image 177
Constantinius Avatar answered Sep 22 '22 01:09

Constantinius


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.

like image 27
kitsu.eb Avatar answered Sep 23 '22 01:09

kitsu.eb