使用 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
.
我尝试使用 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
.