import sys from lxml import etree node_project = { "name": "project", "attr": { "name": "测试", "version": "V1.0.0", "description": "自动化生成测试画面监控配置文件" } } node_canvas = { "name": "canvas", "attr": { "width": "1280", "height": "720", "backgroundColor": "#000000", "name": "", "version": "V1.0.0", "description": "", "lastModified": "", "lastModifiedBy": "", "default": "0" } } label = { "name": "Label", "property": { "x": 0, "y": 0, "width": 800, "height": 20, "text": "", "font": "SimSun,9,-1,5,50,0,0,0,0,0", "fontColor": "#a0a0a4", "backgroundColor": "#00000000", "borderVisiable": "true", "borderColor": "#a0a0a4", "borderWidth": 1 }, "parameter": { "parameterName": [ ] } } number = { "name": "Number", "property": { "x": 0, "y": 0, "width": 400, "height": 20, "rangeFirst": "[0, 1)", "rangeSecond": "[1, 2)", "rangeThird": "[2, 3)", "rangeFourth": "[3, 4)", "rangeFifth": "[4, 5]", "colorFirst": "#ff0000", "colorSecond": "#ffff00", "colorThird": "#00ff00", "colorFourth": "#ffff00", "colorFifth": "#ff0000", "oorColor": "#ffffff", "currentValue": 0, "backgroundColor": "#00000000", "unit": None, "borderVisible": True, "borderWidth": 2, "font": "SimSum,10,-1,5,50,0,0,0,0,0", "decimals": 8 }, "parameter": { "parameterName": [ ] } } binary = { "name": "Binary", "property": { "x": 0, "y": 0, "width": 400, "height": 20, "backgroundColor": "#00000000", "borderVisiable": True, "borderWidth": 1, "font": "SimSun,9,-1,5,50,0,0,0,0,0", "rangeFirst": "[0, 1)", "rangeSecond": "[1, 2]", "colorFirst": "#ff0000", "colorSecond": "#ffff00", "oorColor": "#ffffff", "currentBinary": "0b0" }, "parameter": { "parameterName": [ ] } } def control_dict_to_node(control_dict, parent=None): control_node = etree.Element(control_dict["name"]) if parent is not None: parent.append(control_node) # property if "property" in control_dict: prop_node = etree.SubElement(control_node, "property") for k, v in control_dict["property"].items(): child = etree.SubElement(prop_node, k) if v is None: continue elif isinstance(v, bool): child.text = "true" if v else "false" else: child.text = str(v) # parameter if "parameter" in control_dict: param_node = etree.SubElement(control_node, "parameter") for k, v in control_dict["parameter"].items(): # 多个 parameterName if isinstance(v, list): for item in v: etree.SubElement(param_node, k).text = str(item) else: etree.SubElement(param_node, k).text = str(v) return control_node def get_parameters(filename: str) -> dict: # 读取 XML 文件 tree = etree.parse(filename) # 替换为你的文件路径 root = tree.getroot() # 将结果转为字典 parameters = {msg.get('ParameterName'): msg.get('NormalizedDataType') for msg in root.xpath('//Message')} # 打印字典 # for param, dtype in parameters.items(): # print(f"{param}: {dtype}") for idx, (param, dtype) in enumerate(parameters.items(), start = 0): print(f"{idx}: param = {param}, dtype = {dtype}") return parameters def generate_monitor_xml(filename: str, cal_parameters: list): parameters = get_parameters(filename) # ========= project 根节点 ========= project = etree.Element( node_project["name"], **node_project.get("attr", {}) ) canvas_index = 0 for idx, (param, dtype) in enumerate(parameters.items(), start = 0): # 如果当前 canvas 已满 36 组,则创建新 canvas if idx % 36 == 0: node_canvas["attr"]["name"] = f"canvas-{canvas_index}" canvas = etree.SubElement( project, node_canvas["name"], **node_canvas.get("attr", {}) ) canvas_index += 1 y_offset = (idx % 36) * 20 # Label lbl_ctrl = label.copy() lbl_ctrl["property"] = label["property"].copy() lbl_ctrl["property"]["y"] = y_offset lbl_ctrl["property"]["text"] = param control_dict_to_node(lbl_ctrl, canvas) # 数据控件 if dtype == "BINARY": bin_ctrl = binary.copy() bin_ctrl["property"] = binary["property"].copy() bin_ctrl["property"]["x"] = lbl_ctrl["property"]["width"] + 80 bin_ctrl["property"]["y"] = y_offset bin_ctrl["parameter"]["parameterName"] = [param] control_dict_to_node(bin_ctrl, canvas) else: num_ctrl = number.copy() num_ctrl["property"] = number["property"].copy() num_ctrl["property"]["x"] = lbl_ctrl["property"]["width"] + 80 num_ctrl["property"]["y"] = y_offset num_ctrl["parameter"]["parameterName"] = [param] control_dict_to_node(num_ctrl, canvas) for idx, param in enumerate(cal_parameters, start = 0): if idx % 36 == 0: node_canvas["attr"]["name"] = f"canvas-{canvas_index}" canvas = etree.SubElement( project, node_canvas["name"], **node_canvas.get("attr", {}) ) canvas_index += 1 y_offset = (idx % 36) * 20 # Label lbl_ctrl = label.copy() lbl_ctrl["property"] = label["property"].copy() lbl_ctrl["property"]["y"] = y_offset lbl_ctrl["property"]["text"] = param control_dict_to_node(lbl_ctrl, canvas) num_ctrl = number.copy() num_ctrl["property"] = number["property"].copy() num_ctrl["property"]["x"] = lbl_ctrl["property"]["width"] + 80 num_ctrl["property"]["y"] = y_offset num_ctrl["parameter"]["parameterName"] = [param] control_dict_to_node(num_ctrl, canvas) # ========= 写入文件 ========= tree = etree.ElementTree(project) tree.write( "monitor.xml", encoding="UTF-8", xml_declaration=True, pretty_print=True ) print("canvas count: ", canvas_index) if __name__ == "__main__": if(len(sys.argv) <= 1): print("Missing data process XML file name") print("Try run \'python generate_monitor_configure.py dataprocess.xml\'") sys.exit(1) cal_parameters = [ "cal_parameter1", "cal_parameter2" ] filename = sys.argv[1] generate_monitor_xml(filename, cal_parameters)