使用 ElementTree 在 Python 中解析 XML - findall()

问题描述

我正在使用此处的文档来尝试仅获取某些元素的值(地址、掩码)。

这是我的 XML 结构的示例:

    <?xml version="1.0" ?>
<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="urn:uuid:52622325-b136-40cf-bc36-85332e25b6f3" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">
    <data>
            <native xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-native">
                    <interface>
                            <GigabitEthernet>
                                    <name>1</name>
                                    <ip>
                                            <address>
                                                    <primary>
                                                            <address>192.168.40.30</address>
                                                            <mask>255.255.255.0</mask>
                                                    </primary>
                                            </address>
                                    </ip>
                                    <logging>
                                            <event>
                                                    <link-status/>
                                                    </event>
                                            </logging>
                                            <mop>
                                                    <enabled>false</enabled>
                                                    <sysid>false</sysid>
                                            </mop>
                                            <negotiation xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-ethernet">
                                                    <auto>true</auto>
                                            </negotiation>
                                    </GigabitEthernet>
                                    <GigabitEthernet>
                                            <name>2</name>
                                            <ip>
                                                    <address>
                                                            <primary>
                                                                    <address>10.10.10.1</address>
                                                                    <mask>255.255.255.0</mask>
                                                            </primary>
                                                    </address>
                                            </ip>
                                            <logging>
                                                    <event>
                                                            <link-status/>
                                                    </event>
                                            </logging>
                                            <mop>
                                                    <enabled>false</enabled>
                                                    <sysid>false</sysid>
                                            </mop>
                                            <negotiation xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-ethernet">
                                                    <auto>true</auto>
                                            </negotiation>
                                    </GigabitEthernet>
                                    <GigabitEthernet>
                                            <name>3</name>
                                            <ip>
                                                    <address>
                                                            <primary>
                                                                    <address>30.30.30.1</address>
                                                                    <mask>255.255.255.0</mask>
                                                            </primary>
                                                    </address>
                                            </ip>
                                            <logging>
                                                    <event>
                                                            <link-status/>
                                                    </event>
                                            </logging>
                                            <mop>
                                                    <enabled>false</enabled>
                                                    <sysid>false</sysid>
                                            </mop>
                                            <negotiation xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-ethernet">
                                                    <auto>true</auto>
                                            </negotiation>
                                    </GigabitEthernet>
                                    <GigabitEthernet>
                                            <name>4</name>
                                            <logging>
                                                    <event>
                                                            <link-status/>
                                                    </event>
                                            </logging>
                                            <mop>
                                                    <enabled>false</enabled>
                                                    <sysid>false</sysid>
                                            </mop>
                                            <negotiation xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-ethernet">
                                                    <auto>true</auto>
                                            </negotiation>
                                    </GigabitEthernet>
                            </interface>
                    </native>
            </data>

处理文档中的这个例子,我尝试过这样的事情:

import xml.etree.ElementTree as ET
tree = ET.parse("C:\\Users\\Redha\\Documents\\test_network\\interface123.xml")
root = tree.getroot()

for i in root.findall('native'):  
  print(i.tag)

但它什么都不返回。我试过其他的东西都没有成功。有任何想法吗?所有建议表示赞赏。谢谢!

解决方法

在引用 XML 元素时考虑使用命名空间:

import xml.etree.ElementTree as ET

# declare XML namespaces
namespaces = {'native': 'http://cisco.com/ns/yang/Cisco-IOS-XE-native'}

tree = ET.parse("C:\\Users\\Redha\\Documents\\test_network\\interface123.xml")
root = tree.getroot()

# call findall() using previously created namespaces map
for i in root.findall('.//native:native',namespaces):  
  print(i.tag)