Python Minidom XML解析点四/嵌套子元素

0 投票
1 回答
613 浏览
提问于 2025-04-17 19:52

我有一个非常庞大的列表,里面有各种各样的对象需要解析,我有几个问题:

  1. 我可以很容易地解析XML中的字符串值(比如主机名、颜色、类名等),但是对于任何数字类型的内容(比如IP地址、子网掩码等),我解析得不太对。怎么才能正确显示点分十进制的格式呢?

  2. 使用minidom从更深层的子元素中提取信息的正确方法是什么?(比如Group对象 - 需要在reference下的'name')

  3. 当某个字段没有值时(比如子网掩码),我该如何清理掉错误的[]?

XML看起来像下面这两种输出之一(经过清理):

a) 主机对象:

<network_object>
<Name>DB1</Name>
<Class_Name>host_plain</Class_Name>
<color><![CDATA[black]]></color>
<ipaddr><![CDATA[192.168.100.100]]></ipaddr>

b) 组对象(包含多个成员):

  <network_object>
<Name>DB_Servers</Name>
<Class_Name>network_object_group</Class_Name>
<members>
  <reference>
    <Name>DB1</Name>
    <Table>network_objects</Table>
  </reference>
  <reference>
    <Name>DB2</Name>
    <Table>network_objects</Table>
  </reference>
</members>
<color><![CDATA[black]]></color>

我代码的当前输出对于主机对象是这样的:

DB1 host_plain black [<DOM Element: ipaddr at 0x2d05a50>] []

对于网络对象:

Net_192.168.100.0 network black [<DOM Element: ipaddr at 0x399add0>] [<DOM Element: netmask at 0x399af10>]

对于组对象:

DB_Servers network_object_group black [] []

我的代码:

from xml.dom import minidom

net_xml = minidom.parse("network_objects.xml")

NetworkObjectsTag = net_xml.getElementsByTagName("network_objects")[0]

# Pull individual network objects
NetworkObjectTag = NetworkObjectsTag.getElementsByTagName("network_object")

for network_object in NetworkObjectTag:
    name = network_object.getElementsByTagName("Name")[0].firstChild.data
    class_name = network_object.getElementsByTagName("Class_Name")[0].firstChild.data
    color = network_object.getElementsByTagName("color")[0].firstChild.data
    ipaddr = network_object.getElementsByTagName("ipaddr")
    netmask = network_object.getElementsByTagName("netmask")
    print(name,class_name,color,ipaddr,netmask)

编辑:我已经能够得到一些输出来解决第一个问题,但似乎我遇到了一个我不知道的限制。

新代码:

ipElement = network_object.getElementsByTagName("ipaddr")
ipaddr = ipElement.firstChild.data
maskElement = network_object.getElementsByTagName("netmask")
netmask = maskElement.firstChild.data

给我想要的输出,但似乎在6到9个条目后就停止了,并提示'builtins.IndexError: list index out of range'。

1 个回答

0

我已经能解决我所有的问题了,除了如何正确处理网络组对象。关于这个我会单独再发一篇帖子。

这是我新的代码:

from xml.dom import minidom

net_xml = minidom.parse("network_objects.xml")

NetworkObjectsTag = net_xml.getElementsByTagName("network_objects")[0]

# Pull individual network objects
NetworkObjectTag = NetworkObjectsTag.getElementsByTagName("network_object")

for network_object in NetworkObjectTag:
name = network_object.getElementsByTagName("Name")[0].firstChild.data
class_name = network_object.getElementsByTagName("Class_Name")[0].firstChild.data
color = network_object.getElementsByTagName("color")[0].firstChild.data
ipElement = network_object.getElementsByTagName("ipaddr")
if ipElement:    
    ipElement = network_object.getElementsByTagName("ipaddr")[0]
    ipaddr = ipElement.firstChild.data
maskElement = network_object.getElementsByTagName("netmask")
if maskElement:
    maskElement = network_object.getElementsByTagName("netmask")[0]
    netmask = maskElement.firstChild.data
#address_ranges
ipaddr_firstElement = network_object.getElementsByTagName("ipaddr_first")
if ipaddr_firstElement:
    ipaddr_firstElement = network_object.getElementsByTagName("ipaddr_first")[0]
    ipaddr_first = ipaddr_firstElement.firstChild.data
ipaddr_lastElement = network_object.getElementsByTagName("ipaddr_last")
if ipaddr_lastElement:
    ipaddr_lastElement = network_object.getElementsByTagName("ipaddr_last")[0]
    ipaddr_last = ipaddr_lastElement.firstChild.data    
if ipaddr_firstElement:
    print(name,class_name,ipaddr,netmask,ipaddr_first,ipaddr_last,color)
else:
        print(name,class_name,ipaddr,netmask,color)

撰写回答