Find an xml element based on its attribute and change its value

I am using python xmlElementTree and want to assign or change the value of an xml element based on its attribute. Can someone give me an idea how to do this?

For example: Here is an xml file, and I need to set the value for the element "number" based on the attribute "sys / phoneNumber / 1", "sys2 / SMSnumber / 1", etc.

<root> <phoneNumbers> <number topic="sys/phoneNumber/1" update="none" /> <number topic="sys/phoneNumber/2" update="none" /> <number topic="sys/phoneNumber/3" update="none" /> </phoneNumbers> <gfenSMSnumbers> <number topic="sys2/SMSnumber/1" update="none" /> <number topic="sys2/SMSnumber/2" update="none" /> </gfenSMSnumbers> </root> 

edit: added tag root closure in the XML file.

+4
source share
3 answers

You can access the attribute value as follows:

 from elementtree.ElementTree import XML, SubElement, Element, tostring text = """ <root> <phoneNumbers> <number topic="sys/phoneNumber/1" update="none" /> <number topic="sys/phoneNumber/2" update="none" /> <number topic="sys/phoneNumber/3" update="none" /> </phoneNumbers> <gfenSMSnumbers> <number topic="sys2/SMSnumber/1" update="none" /> <number topic="sys2/SMSnumber/2" update="none" /> </gfenSMSnumbers> </root> """ elem = XML(text) for node in elem.find('phoneNumbers'): print node.attrib['topic'] # Create sub elements if node.attrib['topic']=="sys/phoneNumber/1": tag = SubElement(node,'TagName') tag.attrib['attr'] = 'AttribValue' print tostring(elem) 

forget to say if your version of ElementTree is greater than 1.3, you can use XPath:

 elem.find('.//number[@topic="sys/phoneNumber/1"]') 

http://effbot.org/zone/element-xpath.htm

or you can use this simple one:

 for node in elem.findall('.//number'): if node.attrib['topic']=="sys/phoneNumber/1": tag = SubElement(node,'TagName') tag.attrib['attr'] = 'AttribValue' 
+9
source

I am not familiar with xmlElementTree , but if you use something capable of expressing xpath expressions, you can find the value of node by attribute using an expression like this:

 //number[@topic="sys/phoneNumber/1"] 

So using the etree module:

 >>> import lxml.etree as etree >>> doc = etree.parse('foo.xml') >>> nodes = doc.xpath('//number[@topic="sys/phoneNumber/1"]') >>> nodes [<Element number at 0x10348ed70>] >>> etree.tostring(nodes[0]) '<number topic="sys/phoneNumber/1" update="none"/>\n ' 
+1
source

larsks explains how to use XPath to find what you are after very well. You also wanted to change the attribute. The best way is probably to add a new attribute and delete the original. As soon as you get the result of the node, this is a list with one record (number).

 # This returns sys/phoneNumber/1 nodes[0].get("topic") # To change the value, use set nodes[0].set("topic", "new/value/of/phone/number") 

Hope this helps.

In addition, your final root tag is not closing properly.

0
source

Source: https://habr.com/ru/post/1402572/


All Articles