使用 python 从 xml 获取所有具有相同名称的元素

Get all element with same name from xml using python

我尝试使用 xml.etree.ElementTree 从 config.xml 获取所有“用户名”元素。 但是无法使用下面的代码获取数据,它 return None 给我。

import xml.etree.ElementTree as ET
tree = ET.parse('config.xml')
root = tree.getroot()
users = tree.findall('username')
print(users)

如果我使用上面的代码再次测试一些正常的 xml 文件,它会起作用。 这是我必须使用的 config.xml 文件,也许这个文件中存在格式问题,但我无法弄清楚。

<?xml version="1.0" encoding="UTF-8"?>
<rpc-reply
    xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="urn:uuid:cf3e02a2-b7bc-475f-a87e-b6571eca99b7"
    xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">
    <data>
        <app-hosting-cfg-data
            xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-app-hosting-cfg">
            <apps>
                <app>
                    <application-name>guestshell</application-name>
                    <application-network-resource>
                        <management-interface-name>0</management-interface-name>
                    </application-network-resource>
                </app>
            </apps>
        </app-hosting-cfg-data>
        <native
            xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-native">
            <version>17.3</version>
            <boot-start-marker/>
            <boot-end-marker/>
            <enable>
                <secret>
                    <type>9</type>
                    <secret>$GNcSrWbM1PyCqU.BCza34ClqbgyABGzRV1v5hjCWhaoN9K.gqxCtcCvE</secret>
                </secret>
            </enable>
            <username>
                <name>developer</name>
                <privilege>15</privilege>
                <secret>
                    <encryption>9</encryption>
                    <secret>$oNguEA9um9vRx.$MsDk0DOy1rzBjKAcySWdNjoKcA7GetG9YNnKOs8S67A</secret>
                </secret>
            </username>
            <username>
                <name>netconf</name>
                <privilege>15</privilege>
                <secret>
                    <encryption>9</encryption>
                    <secret>$A7TadNm7VSWsXk$k0eVomchjOb90cjpI5hmLA/n0xlomzUhJ47o5y9WMHc</secret>
                </secret>
            </username>
            <username>
                <name>restconf</name>
                <privilege>15</privilege>
                <secret>
                    <encryption>9</encryption>
                    <secret>$eGCL$P15Lf8exJZB3qk$XYVi2eHOhT895Rpx1gYEQcwWfeML3AavoI/lxrMMtD.</secret>
                </secret>
            </username>
            <username>
                <name>root</name>
                <privilege>15</privilege>
                <secret>
                    <encryption>9</encryption>
                    <secret>$IRHgr7MCAEFNLk$ZfOrXoRLFhh6gHIxhLPfOC9KzjIWISv4KqkNAR51kmI</secret>
                </secret>
            </username>
        </native>
    </data>
</rpc-reply>

可能与 重复。

在此基础上你可以做:

namespaces = {
    'Cisco-IOS-XE-native': "http://cisco.com/ns/yang/Cisco-IOS-XE-native"
}
for node in tree.findall(".//Cisco-IOS-XE-native:username", namespaces):
    print(node)

名称空间有多烦人,对吧?

这个简单的 XPath 表达式从整个树的任何位置选择任何(或没有)名称空间中名为 username 的所有标签。

users = tree.findall('.//{*}username')

输出:

[<Element '{http://cisco.com/ns/yang/Cisco-IOS-XE-native}username' at 0x000002352F7529D0>, <Element '{http://cisco.com/ns/yang/Cisco-IOS-XE-native}username' at 0x000002352F751620>, <Element '{http://cisco.com/ns/yang/Cisco-IOS-XE-native}username' at 0x000002352F750CC0>, <Element '{http://cisco.com/ns/yang/Cisco-IOS-XE-native}username' at 0x000002352F751FD0>]

值得注意的是,tree.findall('username') 仅查找名为 username 的标签,这些标签是 tree 的 children。它不会递归搜索(即整棵树)。这样的话,tree只有一个child,data.