如何在Python中按safetyreportid将XML特定节点复制到指定层级
这里有两种可靠的方案来实现你的XML合并需求——基于safetyreportid将源文件中对应分组的<drug>节点复制到目标文件的<concmed>节点内:
方法1:使用Python的xml.etree.ElementTree
这是一个灵活的脚本化方案,适合需要自定义逻辑的场景:
import xml.etree.ElementTree as ET # 解析源文件和目标文件 source_tree = ET.parse('ExampleSource.xml') source_root = source_tree.getroot() dest_tree = ET.parse('ExampleDestination.xml') dest_root = dest_tree.getroot() # 构建safetyreportid到drug节点列表的映射 drug_map = {} for concmed in source_root.findall('.//concmed'): report_id = concmed.get('safetyreportid') drugs = concmed.findall('.//drug') drug_map[report_id] = drugs # 遍历目标文件的每个safetyreport,匹配并插入drug节点 for safety_report in dest_root.findall('.//safetyreport'): report_id = safety_report.find('safetyreportid').text # 找到当前safetyreport下的concmed节点 concmed = safety_report.find('.//concmed') if concmed is not None and report_id in drug_map: # 复制并添加所有drug节点 for drug in drug_map[report_id]: # 深拷贝节点避免源文件被修改 copied_drug = ET.fromstring(ET.tostring(drug)) concmed.append(copied_drug) # 保存修改后的目标文件 dest_tree.write('MergedResult.xml', encoding='UTF-8', xml_declaration=True)
关键说明:
- 先通过遍历源文件,建立
safetyreportid和对应<drug>节点的映射字典,方便快速查找 - 遍历目标文件的每个
<safetyreport>,提取ID后找到对应的<concmed>节点,将映射中的<drug>节点深拷贝后插入 - 最后保存为新的XML文件,避免覆盖原始目标文件
方法2:使用XSLT转换
如果更倾向于声明式的XML处理方式,可以用XSLT来实现:
首先创建一个XSLT样式表merge_drugs.xsl:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- 从源文件中建立safetyreportid到concmed节点的键映射 --> <xsl:key name="drug-group" match="concmed" use="@safetyreportid"/> <!-- 复制目标文件的所有内容 --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <!-- 匹配目标文件中的concmed节点,插入对应的drug节点 --> <xsl:template match="concmed"> <xsl:copy> <xsl:apply-templates select="@*"/> <!-- 从源文件中获取对应safetyreportid的所有drug节点 --> <xsl:apply-templates select="document('ExampleSource.xml')/drugs/concmed[@safetyreportid=current()/@safetyreportid]/drug"/> </xsl:copy> </xsl:template> </xsl:stylesheet>
然后可以用工具执行转换,比如用xsltproc命令行工具:
xsltproc merge_drugs.xsl ExampleDestination.xml > MergedResult.xml
或者用Python的lxml库执行:
from lxml import etree xslt = etree.parse('merge_drugs.xsl') transform = etree.XSLT(xslt) dest_tree = etree.parse('ExampleDestination.xml') result_tree = transform(dest_tree) result_tree.write('MergedResult.xml', encoding='UTF-8', xml_declaration=True)
关键说明:
- XSLT的核心是通过
<xsl:key>建立源文件的ID映射,然后在匹配目标文件的<concmed>节点时,通过document()函数加载源文件并提取对应ID的<drug>节点 - 这种方式不需要写复杂的遍历逻辑,完全基于XML的结构和规则处理
内容的提问来源于stack exchange,提问作者ndesaintjorre
相关产品推荐
相关产品推荐

