如何使用Python为XML父节点添加子节点(含结构调整示例)
调整PLMRequest XML结构:迁移节点到新建子节点的Python实现
场景1:从JSON转XML时直接调整结构
如果你的XML是从JSON转换而来,先调整JSON数据结构再生成XML会更高效。假设原始JSON数据如下:
{ "PLMRequest": { "StyleNumber": "ST123", "StyleName": "Summer Dress", "Theme": "Beachwear", "ProductSpecialist": "John Doe", "Color": [ {"Code": "BLU", "Name": "Blue"}, {"Code": "RED", "Name": "Red"} ], "Description": "Lightweight cotton dress for summer" } }
修改后的JSON转XML代码如下:
import json import xml.etree.ElementTree as ET def json_to_plm_xml(json_data): plm_data = json_data["PLMRequest"] root = ET.Element("PLMRequest") # 创建Overview节点并迁移指定字段 overview = ET.SubElement(root, "Overview") overview_fields = ["StyleNumber", "StyleName", "Theme", "ProductSpecialist"] for field in overview_fields: if field in plm_data: elem = ET.SubElement(overview, field) elem.text = str(plm_data[field]) del plm_data[field] # 移除已处理字段,避免重复生成 # 创建ColorInfo节点并迁移所有Color项 color_info = ET.SubElement(root, "ColorInfo") if "Color" in plm_data: # 兼容单个Color对象或Color列表的情况 colors = plm_data["Color"] if isinstance(plm_data["Color"], list) else [plm_data["Color"]] for color in colors: color_elem = ET.SubElement(color_info, "Color") for key, val in color.items(): sub_elem = ET.SubElement(color_elem, key) sub_elem.text = str(val) del plm_data["Color"] # 处理剩余未迁移的节点 for key, val in plm_data.items(): elem = ET.SubElement(root, key) elem.text = str(val) # 格式化XML缩进(Python 3.9+支持) ET.indent(root) return ET.tostring(root, encoding="utf-8", xml_declaration=True).decode("utf-8") # 示例调用 if __name__ == "__main__": raw_json = '''{ "PLMRequest": { "StyleNumber": "ST123", "StyleName": "Summer Dress", "Theme": "Beachwear", "ProductSpecialist": "John Doe", "Color": [{"Code": "BLU", "Name": "Blue"}, {"Code": "RED", "Name": "Red"}], "Description": "Lightweight cotton dress for summer" } }''' xml_result = json_to_plm_xml(json.loads(raw_json)) print(xml_result)
关键逻辑说明
- 先创建
Overview节点,遍历指定的字段,将对应的JSON值生成子节点并移入Overview,同时删除原JSON中的这些字段,避免重复生成节点。 - 处理
Color字段时,先统一转为列表(兼容单个/多个Color的情况),逐个生成Color节点并移入ColorInfo,同样删除原JSON中的Color字段。 - 最后处理剩余的其他字段,直接添加到
PLMRequest根节点下。
场景2:直接修改已有的XML文件
如果已经有现成的XML文件,可直接操作XML节点完成迁移。假设现有XML结构如下:
<PLMRequest> <StyleNumber>ST123</StyleNumber> <StyleName>Summer Dress</StyleName> <Theme>Beachwear</Theme> <ProductSpecialist>John Doe</ProductSpecialist> <Color> <Code>BLU</Code> <Name>Blue</Name> </Color> <Color> <Code>RED</Code> <Name>Red</Name> </Color> <Description>Lightweight cotton dress for summer</Description> </PLMRequest>
修改XML结构的代码如下:
import xml.etree.ElementTree as ET def restructure_plm_xml(input_path, output_path): tree = ET.parse(input_path) root = tree.getroot() # 创建Overview节点并迁移指定节点 overview = ET.SubElement(root, "Overview") target_nodes = ["StyleNumber", "StyleName", "Theme", "ProductSpecialist"] for node_name in target_nodes: nodes = root.findall(node_name) for node in nodes: overview.append(node) # append会自动将节点从原父节点移除 # 创建ColorInfo节点并迁移所有Color节点 color_info = ET.SubElement(root, "ColorInfo") color_nodes = root.findall("Color") for color_node in color_nodes: color_info.append(color_node) # 格式化并保存修改后的XML ET.indent(root) tree.write(output_path, encoding="utf-8", xml_declaration=True) # 示例调用 if __name__ == "__main__": restructure_plm_xml("original_plm.xml", "modified_plm.xml")
关键逻辑说明
- 使用
findall定位需要迁移的节点,通过append方法将节点移动到新的子节点下(ElementTree中,节点只能属于一个父节点,append后会自动从原父节点移除)。 - 最后保存修改后的XML文件到指定路径。
内容的提问来源于stack exchange,提问作者Pranit Gursale
相关产品推荐
相关产品推荐

