【问题标题】:Using xpath with lxml.etree._ElementTree将 xpath 与 lxml.etree._ElementTree 一起使用
【发布时间】:2015-07-15 06:31:31
【问题描述】:

我有一个对象 arptree,我试图定位一个 IP 地址的 MAC 地址,但失败了。

>>> arptree 
<lxml.etree._ElementTree object at 0x0000000004641688>

当我尝试以下 xpath 时,它返回一个空列表

>>> arptree.xpath("descendant::mac-address[following-sibling::ip-address='10.69.119.150']")
[]

如果我修改 xpath 以排除“='10.69.119.150'”,它实际上会返回一个元素列表。

>>> arptree.xpath("descendant::mac-address[following-sibling::ip-address]")                      

[, , , , , , , , , ]

我可以使用 for 循环来访问内容。我确定 ip-address 10.69.119.150 的 mac-address 在那里。

for elt in arptree.iter():
    print elt.tag, elt.text

奇怪的是,如果我将 xml 输出复制并粘贴到 xml 文件中。 然后使用:

from lxml import etree
tree = etree.parse(open('arp.xml'))
tree.xpath("descendant::mac-address[following-sibling::ip-address='10.69.119.150']")

它将返回ip地址的mac地址。

我正在使用带有 lxml 包的 Python 2.7.9。 有人可以帮忙吗?

更新 1:示例 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>

更新 2:请忽略更新 1

当我使用时

arptree = ex.device.rpc.get_arp_table_information().getroottree()
arptree.write('arptree.xml', pretty_print=True)

要将 ElementTree 保存到 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>

也许这就是为什么下面的代码不起作用???

arptree.xpath("descendant::mac-address[following-sibling::ip-address='10.69.119.150']")

根据这个xml文件,谁能帮忙?

【问题讨论】:

  • 能否提供一个 XML 示例?
  • 您首先如何获得您的arptreefromstring?
  • 我将在帖子中提供一个示例
  • @Anzel 我使用 Juniper PyEz 包特定的方法获得了 arptree。 arptree = device.rpc.get_arp_table_information().getroottree()。 device.rpc.get_arp_table_information() 本身返回一个lxml.etree._Element的对象
  • 是否可以仅使用 lxml 重现问题,还是我需要 PyEz 来做到这一点?

标签: python xpath lxml


【解决方案1】:

在第二个 XML 中,IP 地址值前后都有换行符。您可以使用normalize-space() 函数来修复它:

descendant::mac-address[following-sibling::ip-address[normalize-space()='10.69.119.150']]

演示的工作示例:

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))

输出:

<mac-address>
00:0f:bb:c6:26:3d
</mac-address>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-12-05
    • 1970-01-01
    • 2020-09-11
    • 2011-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多