You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Python ElementTree从BACnet格式XML文件提取指定属性与Value值

问题根因

你初始代码无法读取<Value>内容的核心问题是调用了prop.get('Value')方法:该方法仅用于提取当前节点的属性值,而<Value>是<Property>的子节点,并非属性,所以只能通过查找子节点后读取.text属性获取内容。

实现方案

你后续补充的代码已经解决了这个问题,核心逻辑完全正确:遍历每个<Object>节点后,查找子节点<Property>下的<Value>,读取其文本内容,再按规则拆分字段输出。如果需要进一步简化代码、提升可维护性,可参考如下优化写法:

import xml.etree.ElementTree as ET
import csv

def parse_bacnet_xml(xml_path, output_csv=None):
    tree = ET.parse(xml_path)
    results = []
    # 遍历所有Object节点
    for obj in tree.findall('Objects/Object'):
        # 直接读取Object自带的Type和Instance属性
        obj_type = obj.attrib.get('Type', '')
        obj_instance = obj.attrib.get('Instance', '')
        # 用字典存储需要提取的Property字段,避免重复定义全局变量
        prop_map = {
            'PROP_OBJECT_IDENTIFIER': '',
            'PROP_OBJECT_NAME': '',
            'PROP_DESCRIPTION': '',
            '3019': ''
        }
        # 遍历Property节点,只读取需要的Id对应值
        for prop in obj.findall('Properties/Property'):
            prop_id = prop.attrib.get('Id')
            if prop_id not in prop_map:
                continue
            # 查找Value子节点,不存在则默认空字符串
            value_node = prop.find('Value')
            prop_map[prop_id] = value_node.text.strip() if value_node is not None else ''
        
        # 字段拆分逻辑
        obj_ident = prop_map['PROP_OBJECT_IDENTIFIER']
        obj_name = prop_map['PROP_OBJECT_NAME']
        obj_desc = prop_map['PROP_DESCRIPTION']
        obj_addr = prop_map['3019']

        # 拆分标识符和实例编号
        identifier, instance = obj_ident.split(':', 1) if ':' in obj_ident else (obj_ident, obj_instance)
        # 拆分对象路径和名称
        if "'" in obj_name:
            *path_parts, name = obj_name.split("'")
            path = "'".join(path_parts)
        else:
            path, name = '', obj_name
        # 拆分总线类型和实际地址
        bus, addr = obj_addr.split('=', 1) if '=' in obj_addr else ('', obj_addr)
        
        row = [identifier, instance, path, name, bus, addr, obj_desc]
        results.append(row)
        print(' , '.join(row))
    
    # 可选直接输出到CSV,避免手动拼接逗号出现格式错误
    if output_csv:
        headers = ['对象类型', '实例编号', '对象路径', '对象名称', '总线类型', '实际地址', '描述']
        with open(output_csv, 'w', encoding='utf-8', newline='') as f:
            writer = csv.writer(f)
            writer.writerow(headers)
            writer.writerows(results)

if __name__ == '__main__':
    parse_bacnet_xml('AS01.xml', output_csv='bacnet_result.csv')

优化点说明:

  • 直接读取<Object>节点自带的Type和Instance属性,可作为PROP_OBJECT_IDENTIFIER拆分失败的兜底
  • 用字典存储需要提取的Property,减少重复的全局变量重置逻辑
  • 内置CSV写入能力,避免手动拼接逗号可能出现的格式错误
  • 用Python内置的拆分方法简化字符串处理逻辑,代码更易读

内容的提问来源于stack exchange,提问作者Zoltan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 16:54:01