如何使用 Python 和 ElementTree 挖掘 XML 文件中的字段数据
How do I dig out field data in the XML file using Python and ElementTree
我正在尝试使用 Python 和 ElementTree 模块从 weathergoose 设备读取 XML 数据。我可以从 'device' 节点获取 "name" 数据,但我想读取 'device' 节点下列出的数据。特别是,我想要 "TempF"
的值
这是 XML 数据的示例:
<server host="WeatherGoose" address="10.0.0.11" <omited stuff> tempunit="F">
<devices>
<device id="0114BE53110000E6" name="WeatherGoose" type="WxGoos" available="1" index="0">
<field key="TempC" value="20.55" niceName="Temperature (C)" min="-20" max="50" type="2"/>
<field key="TempF" value="68.99" niceName="Temperature (F)" min="-4" max="122" type="2"/>
<field key="Humidity" value="42.00" niceName="Relative Humidity" min="0" max="99" type="2"/>
<field key="Airflow" value="33.27" niceName="Air Flow" min="0" max="100" type="2"/>
<field key="Light" value="2.00" niceName="Light Level" min="1" max="99" type="2"/>
<field key="Sound" value="30.00" niceName="Sound Level" min="0" max="99" type="2"/>
<field key="IO1" value="99.00" niceName="Moisture" min="0" max="99" type="2"/>
<field key="IO2" value="99.00" niceName="IO-2" min="0" max="99" type="2"/>
<field key="IO3" value="0.00" niceName="Door Contacts" min="0" max="99" type="2"/>
</device>
</devices>
</server>
这是我目前的情况:
import os
import urllib
import xml.etree.ElementTree as ET
def main():
feed = urllib.urlopen("http://10.0.0.11/data.xml")
try:
tree = ET.parse(feed)
root = tree.getroot()
event = root.find("devices")
for e in event:
print e.attrib['name']
except Exception, inst:
print "Error: %s: %s" % (tree, inst)
if __name__ == "__main__":
main()
这会生成设备的主机名,但我找不到挖掘 'field key' 数据的魔法。任何帮助将不胜感激。
您应该能够 select field
具有 key
属性且值为 TempF
的元素,方法是使用 xpath field[@key='TempF']
(当前元素上下文为 device
).
示例(将 feed
改回您的 urllib 调用)...
def main():
feed = "test.xml" # Used an external file for testing.
try:
tree = ET.parse(feed)
root = tree.getroot()
devices = root.findall("devices/device")
for device in devices:
print device.get("name")
print device.find("field[@key='TempF']").get("value")
except Exception, inst:
print "Error: %s" % inst
这将打印:
WeatherGoose
68.99
注意:如果您有多个 device
元素,这将遍历每个元素。
下面的代码遍历 xml 并填充一个字典,其中键是设备 ID,值是一个字典列表。每个字典代表一个 'field' 属性。仅收集定义为 'interesting' 的字段。
import xml.etree.ElementTree as ET
import pprint
xml = '''<server host="WeatherGoose" address="10.0.0.11" tempunit="F">
<devices>
<device id="0114BE53110000E6" name="WeatherGoose" type="WxGoos" available="1" index="0">
<field key="TempC" value="20.55" niceName="Temperature (C)" min="-20" max="50" type="2"/>
<field key="TempF" value="68.99" niceName="Temperature (F)" min="-4" max="122" type="2"/>
<field key="Humidity" value="42.00" niceName="Relative Humidity" min="0" max="99" type="2"/>
<field key="Airflow" value="33.27" niceName="Air Flow" min="0" max="100" type="2"/>
<field key="Light" value="2.00" niceName="Light Level" min="1" max="99" type="2"/>
<field key="Sound" value="30.00" niceName="Sound Level" min="0" max="99" type="2"/>
<field key="IO1" value="99.00" niceName="Moisture" min="0" max="99" type="2"/>
<field key="IO2" value="99.00" niceName="IO-2" min="0" max="99" type="2"/>
<field key="IO3" value="0.00" niceName="Door Contacts" min="0" max="99" type="2"/>
</device>
</devices>
</server>
'''
root = ET.fromstring(xml)
result = {}
interesting_fields = ['Airflow','TempF']
devices = root.findall('.//devices/device')
for device in devices:
result[device.attrib['id']] = [f.attrib for f in device.findall('./field') if f.attrib['key'] in interesting_fields]
pprint.pprint(result)
输出
{'0114BE53110000E6': [{'key': 'TempF',
'max': '122',
'min': '-4',
'niceName': 'Temperature (F)',
'type': '2',
'value': '68.99'},
{'key': 'Airflow',
'max': '100',
'min': '0',
'niceName': 'Air Flow',
'type': '2',
'value': '33.27'}]}
我正在尝试使用 Python 和 ElementTree 模块从 weathergoose 设备读取 XML 数据。我可以从 'device' 节点获取 "name" 数据,但我想读取 'device' 节点下列出的数据。特别是,我想要 "TempF"
的值这是 XML 数据的示例:
<server host="WeatherGoose" address="10.0.0.11" <omited stuff> tempunit="F">
<devices>
<device id="0114BE53110000E6" name="WeatherGoose" type="WxGoos" available="1" index="0">
<field key="TempC" value="20.55" niceName="Temperature (C)" min="-20" max="50" type="2"/>
<field key="TempF" value="68.99" niceName="Temperature (F)" min="-4" max="122" type="2"/>
<field key="Humidity" value="42.00" niceName="Relative Humidity" min="0" max="99" type="2"/>
<field key="Airflow" value="33.27" niceName="Air Flow" min="0" max="100" type="2"/>
<field key="Light" value="2.00" niceName="Light Level" min="1" max="99" type="2"/>
<field key="Sound" value="30.00" niceName="Sound Level" min="0" max="99" type="2"/>
<field key="IO1" value="99.00" niceName="Moisture" min="0" max="99" type="2"/>
<field key="IO2" value="99.00" niceName="IO-2" min="0" max="99" type="2"/>
<field key="IO3" value="0.00" niceName="Door Contacts" min="0" max="99" type="2"/>
</device>
</devices>
</server>
这是我目前的情况:
import os
import urllib
import xml.etree.ElementTree as ET
def main():
feed = urllib.urlopen("http://10.0.0.11/data.xml")
try:
tree = ET.parse(feed)
root = tree.getroot()
event = root.find("devices")
for e in event:
print e.attrib['name']
except Exception, inst:
print "Error: %s: %s" % (tree, inst)
if __name__ == "__main__":
main()
这会生成设备的主机名,但我找不到挖掘 'field key' 数据的魔法。任何帮助将不胜感激。
您应该能够 select field
具有 key
属性且值为 TempF
的元素,方法是使用 xpath field[@key='TempF']
(当前元素上下文为 device
).
示例(将 feed
改回您的 urllib 调用)...
def main():
feed = "test.xml" # Used an external file for testing.
try:
tree = ET.parse(feed)
root = tree.getroot()
devices = root.findall("devices/device")
for device in devices:
print device.get("name")
print device.find("field[@key='TempF']").get("value")
except Exception, inst:
print "Error: %s" % inst
这将打印:
WeatherGoose
68.99
注意:如果您有多个 device
元素,这将遍历每个元素。
下面的代码遍历 xml 并填充一个字典,其中键是设备 ID,值是一个字典列表。每个字典代表一个 'field' 属性。仅收集定义为 'interesting' 的字段。
import xml.etree.ElementTree as ET
import pprint
xml = '''<server host="WeatherGoose" address="10.0.0.11" tempunit="F">
<devices>
<device id="0114BE53110000E6" name="WeatherGoose" type="WxGoos" available="1" index="0">
<field key="TempC" value="20.55" niceName="Temperature (C)" min="-20" max="50" type="2"/>
<field key="TempF" value="68.99" niceName="Temperature (F)" min="-4" max="122" type="2"/>
<field key="Humidity" value="42.00" niceName="Relative Humidity" min="0" max="99" type="2"/>
<field key="Airflow" value="33.27" niceName="Air Flow" min="0" max="100" type="2"/>
<field key="Light" value="2.00" niceName="Light Level" min="1" max="99" type="2"/>
<field key="Sound" value="30.00" niceName="Sound Level" min="0" max="99" type="2"/>
<field key="IO1" value="99.00" niceName="Moisture" min="0" max="99" type="2"/>
<field key="IO2" value="99.00" niceName="IO-2" min="0" max="99" type="2"/>
<field key="IO3" value="0.00" niceName="Door Contacts" min="0" max="99" type="2"/>
</device>
</devices>
</server>
'''
root = ET.fromstring(xml)
result = {}
interesting_fields = ['Airflow','TempF']
devices = root.findall('.//devices/device')
for device in devices:
result[device.attrib['id']] = [f.attrib for f in device.findall('./field') if f.attrib['key'] in interesting_fields]
pprint.pprint(result)
输出
{'0114BE53110000E6': [{'key': 'TempF',
'max': '122',
'min': '-4',
'niceName': 'Temperature (F)',
'type': '2',
'value': '68.99'},
{'key': 'Airflow',
'max': '100',
'min': '0',
'niceName': 'Air Flow',
'type': '2',
'value': '33.27'}]}