Python解析xml文件,此实例将xml设置为模版(from lxml import etree)

本文解析了ConPot模拟器的template.xml配置文件,详细介绍了如何读取模板详情,包括单位、供应商、描述、协议和创建者信息。同时,深入探讨了数据总线的初始化过程,展示了如何设置各种类型(如值和函数)的数据项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

xml文件(template.xml)

<core>
    <template>
        <!-- General information about the template -->
        <entity name="unit">S7-200</entity>
        <entity name="vendor">Siemens</entity>
        <entity name="description">Rough simulation of a basic Siemens S7-200 CPU with 2 slaves</entity>
        <entity name="protocols">HTTP, MODBUS, s7comm, SNMP</entity>
        <entity name="creator">the conpot team</entity>
    </template>
    <databus>
        <!-- Core value that can be retrieved from the databus by key -->
        <key_value_mappings>
            <key name="FacilityName">
                <value type="value">"Mouser Factory"</value>
            </key>
            <key name="SystemName">
                <value type="value">"Technodrome"</value>
            </key>
            <key name="SystemDescription">
                <value type="value">"Siemens, SIMATIC, S7-200"</value>
            </key>
            <key name="Uptime">
                <value type="function">conpot.emulators.misc.uptime.Uptime</value>
            </key>
            <key name="sysObjectID">
                <value type="value">"0.0"</value>
            </key>
            <key name="sysContact">
                <value type="value">"Siemens AG"</value>
            </key>
            <key name="sysName">
                <value type="value">"CP 443-1 EX40"</value>
            </key>
            <key name="sysLocation">
                <value type="value">"Venus"</value>
            </key>
            <key name="sysServices">
                <value type="value">"72"</value>
            </key>
            <key name="memoryModbusSlave0BlockA">
                <value type="value">[random.randint(0,1) for b in range(0,128)]</value>
            </key>
            <key name="memoryModbusSlave0BlockB">
                <value type="value">[random.randint(0,1) for b in range(0,32)]</value>
            </key>
            <key name="memoryModbusSlave255BlockA">
                <value type="value">[random.randint(0,1) for b in range(0,128)]</value>
            </key>
            <key name="memoryModbusSlave255BlockB">
                <value type="value">[random.randint(0,1) for b in range(0,32)]</value>
            </key>
            <key name="memoryModbusSlave1BlockA">
                <value type="value">[random.randint(0,1) for b in range(0,128)]</value>
            </key>
            <key name="memoryModbusSlave1BlockB">
                <value type="value">[random.randint(0,1) for b in range(0,32)]</value>
            </key>
            <key name="memoryModbusSlave2BlockC">
                <value type="value">[random.randint(0,1) for b in range(0,8)]</value>
            </key>
            <key name="memoryModbusSlave2BlockD">
                <value type="value">[0 for b in range(0,32)]</value>
            </key>
            <key name="Copyright">
                <value type="value">"Original Siemens Equipment"</value>
            </key>
            <key name="s7_id">
                <value type="value">"88111222"</value>
            </key>
            <key name="s7_module_type">
                <value type="value">"IM151-8 PN/DP CPU"</value>
            </key>
            <key name="empty">
                <value type="value">""</value>
            </key>
        </key_value_mappings>
    </databus>
</core>

解析core.template

            template_xml = os.path.join(package_directory, 'templates', folder, 'template.xml')
            if os.path.isfile(template_xml):
                template_unit = template_vendor = template_description = template_protocols = template_creator = 'N/A'
                dom_template = etree.parse(template_xml)
                template_details = dom_template.xpath('//core/template/*')
                if template_details:

                    # retrieve all template details
                    for entity in template_details:

                        if entity.attrib['name'] == 'unit':
                            template_unit = entity.text

                        elif entity.attrib['name'] == 'vendor':
                            template_vendor = entity.text

                        elif entity.attrib['name'] == 'description':
                            template_description = entity.text

                        elif entity.attrib['name'] == 'protocols':
                            template_protocols = entity.text

                        elif entity.attrib['name'] == 'creator':
                            template_creator = entity.text

                    print("   --template {0}".format(folder))
                    print("       Unit:        {0} - {1}".format(template_vendor, template_unit))
                    print("       Desc:        {0}".format(template_description))
                    print("       Protocols:   {0}".format(template_protocols))
                    print("       Created by:  {0}\n".format(template_creator))

结果

--------------------------------------------------
 Available templates:
--------------------------------------------------

   --template IEC104
       Unit:        Siemens - S7-300
       Desc:        Creates a simple device for IEC 60870-5-104
       Protocols:   IEC104, SNMP
       Created by:  Patrick Reichenberger

   --template default
       Unit:        Siemens - S7-200
       Desc:        Rough simulation of a basic Siemens S7-200 CPU with 2 slaves
       Protocols:   HTTP, MODBUS, s7comm, SNMP
       Created by:  the conpot team

   --template proxy
       Unit:        None - Proxy
       Desc:        Sample template that demonstrates the proxy feature.
       Protocols:   Proxy
       Created by:  the conpot team

   --template guardian_ast
       Unit:        Guardian - Guardian AST tank-monitoring system
       Desc:        Guardian AST tank-monitoring system
       Protocols:   guardian_ast
       Created by:  the conpot team

   --template ipmi
       Unit:        IPMI - 371
       Desc:        Creates a simple IPMI device
       Protocols:   IPMI
       Created by:  Lukas Rist

   --template kamstrup_382
       Unit:        Kamstrup - 382
       Desc:        Register clone of an existing Kamstrup 382 smart meter
       Protocols:   Kamstrup
       Created by:  Johnny Vestergaard

解析core.databus

import random
from lxml import etree



def set_value(self, key, value):
        logger.debug('DataBus: Storing key: [%s] value: [%s]', key, value)
        self._data[key] = value
        # notify observers
        if key in self._observer_map:
            gevent.spawn(self.notify_observers, key)


def initialize(self, config_file):
        self.reset()
        assert self.initialized.isSet() is False
        logger.debug('Initializing databus using %s.', config_file)
        dom = etree.parse(config_file)
        entries = dom.xpath('//core/databus/key_value_mappings/*')
        for entry in entries:
            key = entry.attrib['name']
            value = entry.xpath('./value/text()')[0].strip()
            value_type = str(entry.xpath('./value/@type')[0])
            assert key not in self._data
            print ('Initializing key:%s value:%s as a value_type:%s.', key, value, value_type)
            logging.debug('Initializing %s with %s as a %s.', key, value, value_type)
            if value_type == 'value':
                self.set_value(key, eval(value))
            elif value_type == 'function':
                namespace, _classname = value.rsplit('.', 1)
                params = entry.xpath('./value/@param')
                module = __import__(namespace, fromlist=[_classname])
                _class = getattr(module, _classname)
                if len(params) > 0:
                    # eval param to list
                    params = eval(params[0])
                    self.set_value(key, _class(*(tuple(params))))
                else:
                    self.set_value(key, _class())
            else:
                raise Exception('Unknown value type: {0}'.format(value_type))
        self.initialized.set()

结果

Initializing key:%s value:%s as a value_type:%s. FacilityName "Mouser Factory" value
Initializing key:%s value:%s as a value_type:%s. SystemName "Technodrome" value
Initializing key:%s value:%s as a value_type:%s. SystemDescription "Siemens, SIMATIC, S7-200" value
Initializing key:%s value:%s as a value_type:%s. Uptime conpot.emulators.misc.uptime.Uptime function
Initializing key:%s value:%s as a value_type:%s. sysObjectID "0.0" value
Initializing key:%s value:%s as a value_type:%s. sysContact "Siemens AG" value
Initializing key:%s value:%s as a value_type:%s. sysName "CP 443-1 EX40" value
Initializing key:%s value:%s as a value_type:%s. sysLocation "Venus" value
Initializing key:%s value:%s as a value_type:%s. sysServices "72" value
Initializing key:%s value:%s as a value_type:%s. memoryModbusSlave0BlockA [random.randint(0,1) for b in range(0,128)] value
Initializing key:%s value:%s as a value_type:%s. memoryModbusSlave0BlockB [random.randint(0,1) for b in range(0,32)] value
Initializing key:%s value:%s as a value_type:%s. memoryModbusSlave255BlockA [random.randint(0,1) for b in range(0,128)] value
Initializing key:%s value:%s as a value_type:%s. memoryModbusSlave255BlockB [random.randint(0,1) for b in range(0,32)] value
Initializing key:%s value:%s as a value_type:%s. memoryModbusSlave1BlockA [random.randint(0,1) for b in range(0,128)] value
Initializing key:%s value:%s as a value_type:%s. memoryModbusSlave1BlockB [random.randint(0,1) for b in range(0,32)] value
Initializing key:%s value:%s as a value_type:%s. memoryModbusSlave2BlockC [random.randint(0,1) for b in range(0,8)] value
Initializing key:%s value:%s as a value_type:%s. memoryModbusSlave2BlockD [0 for b in range(0,32)] value
Initializing key:%s value:%s as a value_type:%s. Copyright "Original Siemens Equipment" value
Initializing key:%s value:%s as a value_type:%s. s7_id "88111222" value
Initializing key:%s value:%s as a value_type:%s. s7_module_type "IM151-8 PN/DP CPU" value
Initializing key:%s value:%s as a value_type:%s. empty "" value

 

### 如何根据 TXT 文件创建或划分出对应的 XML 文件 #### 方法概述 为了将 TXT 文件的内容转换为 XML 结构,通常需要解析 TXT 文件中的数据并将其映射到目标 XML 格式的节点和属性中。这一过程可以通过编程语言(如 Python 或 Java)完成,也可以借助现有的工具或框架。 --- #### 解决方案 ##### 1. 使用脚本手动转换 以下是基于 Python 的解决方案,展示如何读取 TXT 文件并将内容写入 XML 文件: ```python import xml.etree.ElementTree as ET def txt_to_xml(txt_file, output_xml): # 创建根节点 root = ET.Element("root") with open(txt_file, 'r') as f: lines = f.readlines() for line in lines: item = ET.SubElement(root, "item") # 每行对应一个子节点 text_content = ET.SubElement(item, "text") text_content.text = line.strip() # 去除多余空白字符 tree = ET.ElementTree(root) tree.write(output_xml) # 示例调用 txt_to_xml('input.txt', 'output.xml') ``` 上述代码会将 `input.txt` 中的每一行作为 `<item>` 节点的一部分,并保存为标准的 XML 文件[^5]。 --- ##### 2. 利用现有工具进行批量处理 如果存在大量类似的 TXT 数据文件,则可以考虑使用专门的数据格式转换工具。例如,在 YOLO 数据集中,某些工具已经支持从其他标注格式转换至 XML 格式[^4]。以下是一个可能的工作流程: - **输入**: TXT 文件或其他原始标注文件。 - **中间步骤**: 将 TXT 文件解析成通用的对象表示形式(如字典列表)。 - **输出**: 构建符合需求的 XML 文档结构。 具体实现可参考如下伪代码片段: ```python from lxml import etree def create_yolo_like_xml(image_name, objects_list, output_path): annotation = etree.Element("annotation") folder = etree.SubElement(annotation, "folder").text = "images" filename = etree.SubElement(annotation, "filename").text = image_name size = etree.SubElement(annotation, "size") width = etree.SubElement(size, "width").text = str(640) # 替换实际宽度 height = etree.SubElement(size, "height").text = str(480) # 替换实际高度 depth = etree.SubElement(size, "depth").text = str(3) # RGB 图像默认深度为 3 for obj in objects_list: object_elem = etree.SubElement(annotation, "object") name = etree.SubElement(object_elem, "name").text = obj['class'] bndbox = etree.SubElement(object_elem, "bndbox") xmin = etree.SubElement(bndbox, "xmin").text = str(obj['xmin']) ymin = etree.SubElement(bndbox, "ymin").text = str(obj['ymin']) xmax = etree.SubElement(bndbox, "xmax").text = str(obj['xmax']) ymax = etree.SubElement(bndbox, "ymax").text = str(obj['ymax']) et = etree.ElementTree(annotation) et.write(output_path, pretty_print=True, encoding='utf-8') # 示例调用 objects_data = [ {"class": "dog", "xmin": 100, "ymin": 100, "xmax": 200, "ymax": 200}, {"class": "cat", "xmin": 300, "ymin": 300, "xmax": 400, "ymax": 400} ] create_yolo_like_xml("example.jpg", objects_data, "output.xml") ``` 此函数可以根据给定的目标边界框信息生成类似于 Pascal VOC 的 XML 注解文件[^6]。 --- ##### 3. 自动化与扩展性改进 对于更复杂的场景,建议引入模板引擎技术来动态生成 XML 文件。例如,CodeEngine 提供了一种灵活的方式定义模板行为及其参数化的可能性[^2]。通过预先设计好 XML 输出模式,只需填充必要的变量即可快速生成多个实例文档。 --- #### 注意事项 - 确保 TXT 输入文件具有清晰一致的格式以便于解析。 - 如果涉及图像标注任务,请遵循相应的标签命名约定以保持兼容性[^3]。 - 对于大规模数据集操作时需关注性能瓶颈问题,比如内存消耗过大或者磁盘 I/O 过慢等情况。 --- ####
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

墨痕诉清风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值