【问题标题】:Only print specific xml values that meet two criteria仅打印满足两个条件的特定 xml 值
【发布时间】:2017-01-22 17:54:58
【问题描述】:

我有一个要解析的大型 XML 文件,如果满足两个值,则只打印一个特定值。

这是目前为止的代码:

#!/usr/local/bin/python

import xml.etree.ElementTree as ET
tree = ET.parse('onedb-dhcp.xml')
root = tree.getroot()

# This successfully gets all items in the xml:

print 'This successfully gets all items in the xml:\n'

for p in root.iter('PROPERTY'):
    print p.attrib
print '\n----------------------------------------------------------'

这是示例 xml 文件:

<DATABASE NAME="test" VERSION="43-39" MD5="." SCHEMA-MD5="." INT-VERSION="43-39">
<OBJECT><PROPERTY NAME="__type" VALUE="dhcp.lease"/><PROPERTY NAME="is_invalid_mac" VALUE="false"/><PROPERTY NAME="deferred_ttl" VALUE="300"/><PROPERTY NAME="ack_state" VALUE="renew"/><PROPERTY NAME="v6_prefix_bits" VALUE="0"/><PROPERTY NAME="is_ipv4" VALUE="true"/><PROPERTY NAME="vnode_id" VALUE="79"/><PROPERTY NAME="node_id" VALUE="79"/><PROPERTY NAME="ip_address" VALUE="10.10.1.6"/><PROPERTY NAME="dhcp_range" VALUE="10.10.1.5/10.10.1.254///0/"/><PROPERTY NAME="network_view" VALUE="0"/><PROPERTY NAME="starts" VALUE="2 2017/01/17 04:58:52"/><PROPERTY NAME="ends" VALUE="6 2017/01/21 04:58:52"/><PROPERTY NAME="tstp" VALUE="1 2017/01/23 04:58:52"/><PROPERTY NAME="tsfp" VALUE="1 2017/01/23 04:58:52"/><PROPERTY NAME="atsfp" VALUE="1 2017/01/23 04:58:52"/><PROPERTY NAME="cltt" VALUE="2 2017/01/17 04:58:52"/><PROPERTY NAME="hardware" VALUE="00:1a:4b:26:fd:85"/><PROPERTY NAME="client_hostname" VALUE="&quot;printer1&quot;"/><PROPERTY NAME="binding_state" VALUE="active"/><PROPERTY NAME="next_binding_state" VALUE="expired"/><PROPERTY NAME="variable" VALUE="vendor-class-identifier=&quot;Hewlett-Packard JetDirect&quot; ddns-fwd-name=&quot;printer1.testing.net&quot; ddns-rev-name=&quot;6.1.10.10.in-addr.arpa.&quot; ddns-txt=&quot;0015dce5883b53fa75c8d90d1312f0c054&quot; lt=&quot;04294967295&quot;"/><PROPERTY NAME="ms_server_id" VALUE="."/><PROPERTY NAME="fingerprint" VALUE="HP Printer"/><PROPERTY NAME="fingerprint_class" VALUE="Printers"/></OBJECT>
<OBJECT><PROPERTY NAME="__type" VALUE="dhcp.lease"/><PROPERTY NAME="is_invalid_mac" VALUE="false"/><PROPERTY NAME="deferred_ttl" VALUE="300"/><PROPERTY NAME="ack_state" VALUE="from_peer"/><PROPERTY NAME="v6_prefix_bits" VALUE="0"/><PROPERTY NAME="is_ipv4" VALUE="true"/><PROPERTY NAME="vnode_id" VALUE="86"/><PROPERTY NAME="node_id" VALUE="86"/><PROPERTY NAME="ip_address" VALUE="10.10.1.44"/><PROPERTY NAME="dhcp_range" VALUE="10.10.1.5/101.10.1.254///0/"/><PROPERTY NAME="network_view" VALUE="0"/><PROPERTY NAME="starts" VALUE="2 2017/01/17 04:58:52"/><PROPERTY NAME="ends" VALUE="6 2017/01/21 04:58:52"/><PROPERTY NAME="tstp" VALUE="4 2016/06/23 19:17:54"/><PROPERTY NAME="tsfp" VALUE="1 2017/01/23 04:58:52"/><PROPERTY NAME="atsfp" VALUE="1 2017/01/23 04:58:52"/><PROPERTY NAME="cltt" VALUE="5 2016/06/17 19:17:54"/><PROPERTY NAME="hardware" VALUE="00:1a:4b:26:fd:85"/><PROPERTY NAME="client_hostname" VALUE="&quot;printer2&quot;"/><PROPERTY NAME="binding_state" VALUE="active"/><PROPERTY NAME="next_binding_state" VALUE="expired"/><PROPERTY NAME="variable" VALUE="lt=&quot;345600&quot; ddns-txt=&quot;0015dce5883b53fa75c8d90d1312f0c054&quot; ddns-rev-name=&quot;44.1.10.10.in-addr.arpa.&quot; ddns-fwd-name=&quot;printer2.testing.net&quot; vendor-class-identifier=&quot;Hewlett-Packard JetDirect&quot;"/><PROPERTY NAME="ms_server_id" VALUE="."/></OBJECT>
</DATABASE>

当我运行上面的脚本时,这就是我打印到屏幕上的内容(只是一个示例):

{'NAME': '__type', 'VALUE': 'dhcp.lease'}
{'NAME': 'is_invalid_mac', 'VALUE': 'false'}
{'NAME': 'deferred_ttl', 'VALUE': '300'}
{'NAME': 'ack_state', 'VALUE': 'renew'}
{'NAME': 'v6_prefix_bits', 'VALUE': '0'}
{'NAME': 'is_ipv4', 'VALUE': 'true'}
{'NAME': 'vnode_id', 'VALUE': '79'}
{'NAME': 'node_id', 'VALUE': '79'}
{'NAME': 'ip_address', 'VALUE': '10.10.1.6'}

如果_type = dhcp.lease,我如何将其设置为仅打印ip_address 值?

我试过了:

l = 'dhcp.lease'
ip = 'ip_address'

for s in root.iter('PROPERTY'):
        n = s.attrib['NAME']
        d = s.attrib['VALUE']
        if d == l:
                print s.attrib['VALUE']

打印出来:

Searching for specific things...

dhcp.lease
dhcp.lease

我想我已经接近终点线了,但需要一些帮助才能克服它。

【问题讨论】:

    标签: python xml elementtree


    【解决方案1】:

    您需要先遍历所有对象。如果您找到带有“dhcp.lease”的属性,则打印该对象的“ip_adress”。

    试试这个:

    for obj in tree.iter('OBJECT'):
    
        # Build a dictionary from NAME and VALUE of each property
        properties = dict([
            (p.attrib['NAME'], p.attrib['VALUE'])
            for p in obj.iter('PROPERTY')
        ])
    
        # Skip this object if it's not a dhcp lease
        if properties['__type'] != 'dhcp.lease':
            continue
    
        print properties['ip_address']
    

    我在这里假设您的属性具有唯一的名称,这样我就可以创建一个字典来简化查找。

    如果您想稍后扩展它以添加更多检查,您可以在打印之前添加更多 if 语句。类似(无效的python):if properties['ends'] &lt; now + 7 days: continue

    【讨论】:

    • 这让我更接近了一点。它会找到符合条件的项目数,但它打印的是括号而不是值:Getting IPs... [] [] [] [] []
    • 如果你只得到 [] 则没有 NAME == 'ip_address' 的属性。如果您得到类似['1.2.3.4'] 的内容,则在最后一行将]) 替换为][0])
    • 非常感谢。我对你的样品做了一些小调整,我得到了我想要的。然而,IP 被括号和单引号包围。 ['10.10.1.6']。如何将打印语句更改为仅在每一行上打印一个 IP。
    • 我编辑了代码以删除输出中的括号
    • 完美!非常感谢。你介意解释一下吗?我可能想在将来修改它以跳过其他项目。例如,如果 IP 的租约不在过去 7 天内。租约开始/结束时间在 xml 文件中。
    猜你喜欢
    • 2021-05-16
    • 1970-01-01
    • 2017-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-03
    • 1970-01-01
    • 2013-02-21
    相关资源
    最近更新 更多