Python ElementTree:解析XML曾孙
我已经尝试解析一些XML好几个小时了,但运气不好。检查了类似的线程并查看了ElementTree文档,但仍然很失落 基本上,我从路由器接收到一些XML输出,这些输出存储在一个字符串中,然后我必须对其进行解析,以获得一些特定的信息 下面是我正在研究的xml示例:Python ElementTree:解析XML曾孙,python,xml,automation,elementtree,Python,Xml,Automation,Elementtree,我已经尝试解析一些XML好几个小时了,但运气不好。检查了类似的线程并查看了ElementTree文档,但仍然很失落 基本上,我从路由器接收到一些XML输出,这些输出存储在一个字符串中,然后我必须对其进行解析,以获得一些特定的信息 下面是我正在研究的xml示例: xml = """<rpc-reply xmlns:junos="http://xml.juniper.net/junos/14.1D0/junos"> <route-information xmlns=
xml = """<rpc-reply xmlns:junos="http://xml.juniper.net/junos/14.1D0/junos">
<route-information xmlns="http://xml.juniper.net/junos/14.1D0/junos-routing">
<!-- keepalive -->
<route-table>
<table-name>inet.0</table-name>
<destination-count>52</destination-count>
<total-route-count>52</total-route-count>
<active-route-count>52</active-route-count>
<holddown-route-count>0</holddown-route-count>
<hidden-route-count>0</hidden-route-count>
<rt junos:style="brief">
<rt-destination>5.5.5.5/32</rt-destination>
<rt-entry>
<active-tag>*</active-tag>
<current-active/>
<last-active/>
<protocol-name>Direct</protocol-name>
<preference>0</preference>
<age junos:seconds="428929">4d 23:08:49</age>
<nh>
<selected-next-hop/>
<via>lo0.0</via>
</nh>
</rt-entry>
</rt>
</route-table>
</route-information>
<cli>
<banner></banner>
</cli>
</rpc-reply>"""
这个,
这将在特定节点上设置根(指针?)
x = root.getiterator(tag = "destination-count")
非常感谢您提供有关如何遍历到此特定节点或如何获得所需结果的任何帮助。代码不起作用的原因是名称空间。如果名称空间始终相同,则可以将其编码为要查找的标记的前缀:
import xml.etree.ElementTree as ET
xml = """
<rpc-reply xmlns:junos="http://xml.juniper.net/junos/14.1D0/junos">
<route-information xmlns="http://xml.juniper.net/junos/14.1D0/junos-routing">
<!-- keepalive -->
<route-table>
<table-name>inet.0</table-name>
<destination-count>52</destination-count>
<total-route-count>52</total-route-count>
<active-route-count>52</active-route-count>
<holddown-route-count>0</holddown-route-count>
<hidden-route-count>0</hidden-route-count>
<rt junos:style="brief">
<rt-destination>5.5.5.5/32</rt-destination>
<rt-entry>
<active-tag>*</active-tag>
<current-active/>
<last-active/>
<protocol-name>Direct</protocol-name>
<preference>0</preference>
<age junos:seconds="428929">4d 23:08:49</age>
<nh>
<selected-next-hop/>
<via>lo0.0</via>
</nh>
</rt-entry>
</rt>
</route-table>
</route-information>
<cli>
<banner></banner>
</cli>
</rpc-reply>
"""
XML_NAMESPACE = '{http://xml.juniper.net/junos/14.1D0/junos-routing}'
root = ET.fromstring(xml)
rt_nodes = root.iter(tag='{}rt-destination'.format(XML_NAMESPACE))
print rt_nodes.next().text # 5.5.5.5/32
将xml.etree.ElementTree作为ET导入
xml=”“”
inet.0
52
52
.代码不起作用的原因是命名空间。如果命名空间始终相同,则可以将其编码为要查找的标记的前缀:
import xml.etree.ElementTree as ET
xml = """
<rpc-reply xmlns:junos="http://xml.juniper.net/junos/14.1D0/junos">
<route-information xmlns="http://xml.juniper.net/junos/14.1D0/junos-routing">
<!-- keepalive -->
<route-table>
<table-name>inet.0</table-name>
<destination-count>52</destination-count>
<total-route-count>52</total-route-count>
<active-route-count>52</active-route-count>
<holddown-route-count>0</holddown-route-count>
<hidden-route-count>0</hidden-route-count>
<rt junos:style="brief">
<rt-destination>5.5.5.5/32</rt-destination>
<rt-entry>
<active-tag>*</active-tag>
<current-active/>
<last-active/>
<protocol-name>Direct</protocol-name>
<preference>0</preference>
<age junos:seconds="428929">4d 23:08:49</age>
<nh>
<selected-next-hop/>
<via>lo0.0</via>
</nh>
</rt-entry>
</rt>
</route-table>
</route-information>
<cli>
<banner></banner>
</cli>
</rpc-reply>
"""
XML_NAMESPACE = '{http://xml.juniper.net/junos/14.1D0/junos-routing}'
root = ET.fromstring(xml)
rt_nodes = root.iter(tag='{}rt-destination'.format(XML_NAMESPACE))
print rt_nodes.next().text # 5.5.5.5/32
将xml.etree.ElementTree作为ET导入
xml=”“”
inet.0
52
52
.您缺少路由信息
标记的命名空间。在XML中有两个名称空间,不幸的是,您需要的名称空间没有标记
<rpc-reply xmlns:junos="http://xml.juniper.net/junos/14.1D0/junos">
<route-information xmlns="http://xml.juniper.net/junos/14.1D0/junos-routing">
但是,在下一层中,lxml.etree
知道名称空间”http://xml.juniper.net/junos/14.1D0/junos-routing“
,但由于它没有标签,它将其提取到命名空间映射中,并使用None
作为字典键
>>> nsmap = root.getchildren()[0].nsmap
>>> nsmap
{'junos': 'http://xml.juniper.net/junos/14.1D0/junos',
None: 'http://xml.juniper.net/junos/14.1D0/junos-routing'}
这是一个问题,因为我们不能使用None
引用名称空间。一种选择是只在字典中为创建一个新的名称空间引用http://xml.juniper.net/junos/14.1D0/junos-routing“
nsmap['my_ns'] = nsmap.pop(None)
我们需要在这里使用.pop
,因为lxml
不允许使用None
作为键的命名空间。现在,您可以使用xpath搜索rt destination
标记,并仅返回标记中的文本
root.xpath('.//my_ns:rt-destination/text()', namespaces=nsmap)
您缺少路由信息
标记的命名空间。在XML中有两个名称空间,不幸的是,您需要的名称空间没有标记
<rpc-reply xmlns:junos="http://xml.juniper.net/junos/14.1D0/junos">
<route-information xmlns="http://xml.juniper.net/junos/14.1D0/junos-routing">
但是,在下一层中,lxml.etree
知道名称空间”http://xml.juniper.net/junos/14.1D0/junos-routing“
,但由于它没有标签,它将其提取到命名空间映射中,并使用None
作为字典键
>>> nsmap = root.getchildren()[0].nsmap
>>> nsmap
{'junos': 'http://xml.juniper.net/junos/14.1D0/junos',
None: 'http://xml.juniper.net/junos/14.1D0/junos-routing'}
这是一个问题,因为我们不能使用None
引用名称空间。一种选择是只在字典中为创建一个新的名称空间引用http://xml.juniper.net/junos/14.1D0/junos-routing“
nsmap['my_ns'] = nsmap.pop(None)
我们需要在这里使用.pop
,因为lxml
不允许使用None
作为键的命名空间。现在,您可以使用xpath搜索rt destination
标记,并仅返回标记中的文本
root.xpath('.//my_ns:rt-destination/text()', namespaces=nsmap)