Reputation: 21
I have an object arptree, I am trying to locate the mac-address of an ip-address, but failed.
>>> arptree
<lxml.etree._ElementTree object at 0x0000000004641688>
When I try the following xpath, it returns an empty list
>>> arptree.xpath("descendant::mac-address[following-sibling::ip-address='10.69.119.150']")
[]
If I modify the xpath to exclude "='10.69.119.150'", it actually returns a list of Elements.
>>> arptree.xpath("descendant::mac-address[following-sibling::ip-address]")
[, , , , , , , , , ]
I can use a for loop to access the content. And I am sure the mac-address for ip-address 10.69.119.150 is there.
for elt in arptree.iter():
print elt.tag, elt.text
The strange thing is that if I copy and paste the xml output to a xml file. Then use:
from lxml import etree
tree = etree.parse(open('arp.xml'))
tree.xpath("descendant::mac-address[following-sibling::ip-address='10.69.119.150']")
It will return the mac-address for the ip address.
I'm using Python 2.7.9 with lxml package. Can anyone help?
Update 1: example XML
<arp-table-information>
<arp-table-entry>
<mac-address>00:a0:a5:76:1a:96</mac-address>
<ip-address>10.69.119.130</ip-address>
<hostname>10.69.119.130</hostname>
<interface-name>vlan.49</interface-name>
<arp-table-entry-flags>
<none/>
</arp-table-entry-flags>
</arp-table-entry>
<arp-table-entry>
<mac-address>00:0f:bb:c6:26:3d</mac-address>
<ip-address>10.69.119.150</ip-address>
<hostname>10.69.119.150</hostname>
<interface-name>vlan.55</interface-name>
<arp-table-entry-flags>
<none/>
</arp-table-entry-flags>
</arp-table-entry>
</arp-table-information>
Update 2: Please ignore Update 1
When I use
arptree = ex.device.rpc.get_arp_table_information().getroottree()
arptree.write('arptree.xml', pretty_print=True)
to save the ElementTree to a xml, the layout changes to
<arp-table-information style="normal">
<arp-table-entry>
<mac-address>
00:a0:a5:76:1a:96
</mac-address>
<ip-address>
10.69.119.130
</ip-address>
<hostname>
10.69.119.130
</hostname>
<interface-name>
vlan.49
</interface-name>
<arp-table-entry-flags>
<none/>
</arp-table-entry-flags>
</arp-table-entry>
<arp-table-entry>
<mac-address>
00:0f:bb:c6:26:3d
</mac-address>
<ip-address>
10.69.119.150
</ip-address>
<hostname>
10.69.119.150
</hostname>
<interface-name>
vlan.55
</interface-name>
<arp-table-entry-flags>
<none/>
</arp-table-entry-flags>
</arp-table-entry>
Maybe this is why the following code doesn't work???
arptree.xpath("descendant::mac-address[following-sibling::ip-address='10.69.119.150']")
Based on this xml file, can anyone help?
Upvotes: 2
Views: 1031
Reputation: 89285
In the 2nd XML, you have new line characters before and after the IP address value. You can use normalize-space()
function to fix it :
descendant::mac-address[following-sibling::ip-address[normalize-space()='10.69.119.150']]
working example for demo :
from lxml import etree
xml = """<arp-table-information style="normal">
<arp-table-entry>
<mac-address>
00:a0:a5:76:1a:96
</mac-address>
<ip-address>
10.69.119.130
</ip-address>
<hostname>
10.69.119.130
</hostname>
<interface-name>
vlan.49
</interface-name>
<arp-table-entry-flags>
<none/>
</arp-table-entry-flags>
</arp-table-entry>
<arp-table-entry>
<mac-address>
00:0f:bb:c6:26:3d
</mac-address>
<ip-address>
10.69.119.150
</ip-address>
<hostname>
10.69.119.150
</hostname>
<interface-name>
vlan.55
</interface-name>
<arp-table-entry-flags>
<none/>
</arp-table-entry-flags>
</arp-table-entry>
</arp-table-information>"""
root = etree.fromstring(xml)
result = root.xpath("descendant::mac-address[following-sibling::ip-address[normalize-space()='10.69.119.150']]")
for r in result:
print(etree.tostring(r))
output :
<mac-address>
00:0f:bb:c6:26:3d
</mac-address>
Upvotes: 2