from lxml import objectify, etree root = etree.fromstring('''<?xml version="1.0" encoding="ISO-8859-1" ?> <scenario> <init> <send channel="channel-Gy"> <command name="CER"> <avp name="Origin-Host" value="router1dev"></avp> <avp name="Origin-Realm" value="realm.dev"></avp> <avp name="Host-IP-Address" value="0x00010a248921"></avp> <avp name="Vendor-Id" value="11"></avp> <avp name="Product-Name" value="HP Ro Interface"></avp> <avp name="Origin-State-Id" value="1094807040"></avp> <avp name="Supported-Vendor-Id" value="10415"></avp> <avp name="Auth-Application-Id" value="4"></avp> <avp name="Acct-Application-Id" value="0"></avp> <avp name="Vendor-Specific-Application-Id"> <avp name="Vendor-Id" value="11"></avp> <avp name="Auth-Application-Id" value="4"></avp> <avp name="Acct-Application-Id" value="0"></avp> </avp> <avp name="Firmware-Revision" value="1"> </avp> </command> </send> </init> <traffic> <send channel="channel-Gy" > <action> <inc-counter name="HbH-counter"></inc-counter> .... </action> </send> </traffic> </scenario>''')
How can I modify/set both values?
Host-IP-Address value="0x00010a248921"
"Vendor-Id" value="11"
I've unsuccessfully tried accessing
root.xpath("//scenario/init/send_channel/command[@name='CER']/avp[@name='Host-IP-Address']/value/text()")
Goal: I'd preferably like to see a lxml.objectify vs an Xpath solution but I'll accept other lxml based solutions.
The files are <100kB so speed/RAM is not much of a concern.
lxml is a Python library which allows for easy handling of XML and HTML files, and can also be used for web scraping. There are a lot of off-the-shelf XML parsers out there, but for better results, developers sometimes prefer to write their own XML and HTML parsers.
Parsing from strings and files. lxml. etree supports parsing XML in a number of ways and from all important sources, namely strings, files, URLs (http/ftp) and file-like objects. The main parse functions are fromstring() and parse(), both called with the source as first argument.
In lxml. objectify, this directly translates to enforcing a specific object tree, i.e. expected object attributes are ensured to be there and to have the expected type. This can easily be achieved through XML Schema validation at parse time.
import lxml.etree as et tree = et.fromstring(''' ... your xml ... ''') for host_ip in tree.xpath("/scenario/init/send/command[@name='CER']/avp[@name='Host-IP-Address']"): host_ip.attrib['value'] = 'foo' print et.tostring(tree)
You could try this:
r = etree.fromstring('...') element = r.find('//avp[@name="Host-IP-Address"]') # Access value print 'Current value is:', element.get('value') # change value element.set('value', 'newvalue')
Also, note that in your example you're using the text()
method, but that's not what you want: the "text" of an element is what is enclosed by the element. For example, given this:
<someelement>this is the text</someelement>
The value of the text()
method on the <somevalue>
element is "this is the text".
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