Reputation: 39
I have an XML string where I want to modify the model type for specific interface.
<domain type='kvm'>
<devices>
<interface type='network'>
<mac address='52:54:00:a8:fe:3d'/>
<source network='ovirtmgmt'/>
<model type='virtio'/>
</interface>
<interface type='network'>
<mac address='52:54:00:a8:fe:7d'/>
<source network='nat'/>
<model type='virtio'/>
</interface>
<interface type='network'>
<mac address='52:80:00:a8:66:20'/>
<source network='vm'/>
<model type='virtio'/>
</interface>
</devices>
</domain>
Now, I want to change model type='e1000'
where source network='nat'
. How can I do that?
Upvotes: 0
Views: 144
Reputation: 168796
You don't need multiple find*()
calls. You can do it in one call:
from xml.etree import ElementTree as ET
tree = ET.parse('input.xml')
for model in tree.findall(".//source[@network='nat']/../model"):
model.set('type', 'e1000')
tree.write('output.xml')
Upvotes: 1
Reputation: 39
Thanks for your answers, but this is also worked for me
root = ET.fromstring(xml)
for interface in root.findall('devices/interface'):
if interface.find('source/[@network="nat"]') != None:
model = interface.find('model')
model.set('type', 'e1000')
new_xml = ET.tostring(root)
Upvotes: 0
Reputation: 55499
Here's some crude ElementTree code that does the job. In a real program you'd probably want some error checking. But if you're sure your XML data will always be perfect, and that every interface
tag will always contain a source
tag and a model
tag, then this code will do the job.
import xml.etree.cElementTree as ET
data = '''
<domain type='kvm'>
<devices>
<interface type='network'>
<mac address='52:54:00:a8:fe:3d'/>
<source network='ovirtmgmt'/>
<model type='virtio'/>
</interface>
<interface type='network'>
<mac address='52:54:00:a8:fe:7d'/>
<source network='nat'/>
<model type='virtio'/>
</interface>
<interface type='network'>
<mac address='52:80:00:a8:66:20'/>
<source network='vm'/>
<model type='virtio'/>
</interface>
</devices>
</domain>
'''
tree = ET.fromstring(data)
for iface in tree.iterfind('devices/interface'):
network = iface.find('source').attrib['network']
if network == 'nat':
model = iface.find('model')
model.attrib['type'] = 'e1000'
ET.dump(tree)
output
<domain type="kvm">
<devices>
<interface type="network">
<mac address="52:54:00:a8:fe:3d" />
<source network="ovirtmgmt" />
<model type="virtio" />
</interface>
<interface type="network">
<mac address="52:54:00:a8:fe:7d" />
<source network="nat" />
<model type="e1000" />
</interface>
<interface type="network">
<mac address="52:80:00:a8:66:20" />
<source network="vm" />
<model type="virtio" />
</interface>
</devices>
</domain>
If you're using an old version of Python you may not have iterfind
. In which case, replace it with findall
.
Upvotes: 0