I am using python xmlElementTree and want to assign or modify a xml element value based on its attribute. Can somebody give me an idea how to do this?
For example: Here
larsks explains how to use XPath to find what you are after very well. You also wanted to change an attribute. The best way is probably to add a new attribute and remove the original. Once you get the nodes result, it is a list with a single entry (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.
Also, your ending root tag doesn't close properly.
For me this Elementtree snipped of code worked to find element by attribute:
import xml.etree.ElementTree as ET
tree = ET.parse('file.xml')
root = tree.getroot()
topic=root.find(".//*[@topic='sys/phoneNumber/1']").text
I'm not familiar with xmlElementTree
, but if you're using something capable of xpath
expressions you can locate a node by attribute value 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 '
You can access the attribute value as this:
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 ElementTree version 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'