Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python lxml - modify attributes

Tags:

python

xml

lxml

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.

like image 520
Joao Figueiredo Avatar asked Nov 17 '11 16:11

Joao Figueiredo


People also ask

What does lxml do in Python?

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.

What is Etree in lxml?

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.

What is lxml objectify?

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.


2 Answers

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) 
like image 101
Acorn Avatar answered Sep 16 '22 23:09

Acorn


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".

like image 24
larsks Avatar answered Sep 20 '22 23:09

larsks