import json import xml.etree.ElementTree as ET import re import os # 钉子的图片名-ID映射表 screw_pic_to_id_map = {"sg_screw1.png":1,"sg_screw2.png":2,"sg_screw3.png":3} # 盘子的图片名-ID映射表 plate_pic_to_id_map = {"sg_plant1.png":1,"sg_plant0.png":2} # 目标盒子的图片名-ID映射表 target_pic_to_id_map = {"sg-目标容器-1.png":1,"sg-目标容器-2.png":2} def xml_to_dict(root: ET.Element): """将XML文件解析为python dict""" ret_arr = [] ret_dict = {} if root.tag == "dict": idx = 0 while idx < len(root): if root[idx].tag == "key": ret_dict[root[idx].text] = xml_to_dict(root[idx + 1]) idx += 1 idx += 1 return ret_dict elif root.tag == "array": idx = 0 while idx < len(root): ret_arr.append(xml_to_dict(root[idx])) idx += 1 return ret_arr elif root.tag == "plist": for child in root: ret_dict["plist"] = xml_to_dict(child) break return ret_dict else: return root.text def get_target_and_elem_list(conf_dict: dict): """从node_graph字典下获取target(任务目标)和element(元素)的list""" node_graph_dict = conf_dict["plist"]["nodeGraph"]["children"] return node_graph_dict[0]["children"], node_graph_dict[1]["children"] def get_all_target(target_list: list): """获取所有target的list""" all_target_list = [] for dic in target_list: propertieIdx = 0 while True: propertie = dic["properties"][propertieIdx] if propertie["name"] == "displayFrame": displayFrame = propertie["value"][1] break propertieIdx = propertieIdx+1 displayFrame = os.path.basename(displayFrame) resTagrgetId = target_pic_to_id_map[displayFrame] screwIds = [] for target_dict in dic["children"]: # 展示的目标名称可能和采用的图片不一样 所以先不用这个 # display_name_str = target_dict["displayName"] target_properties_list = target_dict["properties"] propertieIdx = 0 while True: propertie = target_properties_list[propertieIdx] if propertie["name"] == "displayFrame": target_pic_name = propertie["value"][1] break propertieIdx = propertieIdx+1 target_pic_name = os.path.basename(target_pic_name) # print (target_pic_name) if target_pic_name not in screw_pic_to_id_map.keys(): screw_pic_to_id_map[target_pic_name] = len(screw_pic_to_id_map) + 1 screwIds.append(screw_pic_to_id_map[target_pic_name]) all_target_list.append({"targetResId":resTagrgetId, "screwIds":screwIds}) return all_target_list def get_plate_data_list(elem_list: list): """获取盘子信息列表""" plate_data = [] for dic in elem_list: plate_property = [] screw_properties = [] for elem_dict in dic["children"]: propertieIdx = 0 while True: propertie = elem_dict["properties"][propertieIdx] if propertie["name"] == "displayFrame": displayFrame = propertie["value"][1] break propertieIdx = propertieIdx+1 displayFrame = os.path.basename(displayFrame) # print (displayFrame) if displayFrame in plate_pic_to_id_map: plate_property.append(elem_dict["properties"]) else: screw_properties.append(elem_dict["properties"]) plate_property = plate_property[0] # 处理盘子的信息 one_plate_data = {} one_plate_data["rotate"] = 0 one_plate_data["scale"] = 1 plate_pic_name = "" for ele in plate_property: dict_values = ele.values() if "displayFrame" in dict_values: plate_pic_name = ele["value"][1] plate_pic_name = os.path.basename(plate_pic_name) elif "rotation" in dict_values: one_plate_data["rotate"] = round(float(ele["value"]), 1) elif "scale" in dict_values: one_plate_data["scale"] = round(float(ele["value"][0]), 1) elif "position" in dict_values: one_plate_data["position"] = [round(float(ele["value"][0])), round(float(ele["value"][1]), 1)] if plate_pic_name not in plate_pic_to_id_map: plate_pic_to_id_map[plate_pic_name] = len(one_plate_data) + 1 one_plate_data["plateId"] = plate_pic_to_id_map[plate_pic_name] one_plate_data["zorder"] = len(plate_data) + 1 # 处理钉子的信息 screws_data = [] for screw in screw_properties: data_dict = {} for property_dict in screw: dict_values = property_dict.values() if "displayFrame" in dict_values: picName = os.path.basename(property_dict["value"][1]) # print(picName) data_dict["screwId"] = screw_pic_to_id_map[picName] break data_dict["scale"] = 1.0 data_dict["rotate"] = 0.0 data_dict["position"] = [round(float(screw[0]["value"][0]), 1), round(float(screw[0]["value"][1]), 1)] screws_data.append(data_dict) one_plate_data["screws"] = screws_data plate_data.append(one_plate_data) return plate_data def py_dict_to_json_file(py_dict: dict, xml_path: str): """将python dict写到JSON文件中""" file_name = re.findall(r"(?=/).*(?=.red)", xml_path)[0] file_name = re.findall(r"[^/]+$", file_name)[0] file_name += ".json" j_data = json.dumps(py_dict) with open("../config/" + file_name, "w") as file: file.write(j_data) if __name__ == "__main__": xml_path = "../关卡/关卡2.red" element_tree = ET.parse(xml_path) conf_dict = xml_to_dict(element_tree.getroot()) target_list, elem_list = get_target_and_elem_list(conf_dict) target_and_plateData_dict = { "target": get_all_target(target_list), "plateData": get_plate_data_list(elem_list) } py_dict_to_json_file(target_and_plateData_dict, xml_path)