Python使用xml.etree.ElementTree筛选SHA-256不同的XML flow节点
使用xml.etree.ElementTree实现需求的落地方案
你可以按照节点定位、值提取、对比筛选的逻辑一步步实现,全程用ElementTree内置的XPath查找方法即可,不需要自己写多层循环遍历节点。
核心实现步骤
- 加载XML数据源:如果是XML文件用
ET.parse(文件路径).getroot()获取根节点,如果是XML格式字符串用ET.fromstring(字符串内容)获取根节点 - 批量获取所有
节点:直接调用根节点的 findall('./flows/flow')方法,就能拿到下全部 子元素的列表 - 单flow内定位两个reference节点:对每个flow节点,用带属性匹配的XPath
./reference[@type='from']和./reference[@type='to'],分别拿到type属性为from和to的两个reference节点 - 提取SHA-256哈希值:在每个reference节点下,用XPath
./app/hashes/hash[@type='SHA-256']定位到存SHA-256值的hash节点,取节点的text属性就是哈希值,记得用.strip()去掉首尾多余的空白字符,避免格式问题导致对比错误 - 筛选符合要求的flow:对比两个哈希值,不相等时用
ET.tostring(flow, encoding='unicode')把当前flow节点转成完整的XML字符串,存入结果列表即可 - 异常兼容:每一步查找节点后都判断下返回值是否为None,遇到XML结构缺项的情况直接跳过,避免程序报错
可直接运行的示例代码
import xml.etree.ElementTree as ET # -------------------------- # 替换成你自己的XML加载逻辑 # 本地文件加载写法: # root = ET.parse("你的xml文件路径.xml").getroot() # 字符串加载写法参考下方示例 # -------------------------- xml_demo = """ <answer> <flows> <flow flow_id="001"> <reference type="from"> <app> <hashes> <hash type="SHA-256">a1b2c3d4e5f6</hash> <hash type="MD5">x1y2z3</hash> </hashes> </app> </reference> <reference type="to"> <app> <hashes> <hash type="SHA-256">a1b2c3d4e5f6</hash> </hashes> </app> </reference> </flow> <flow flow_id="002"> <reference type="from"> <app> <hashes> <hash type="SHA-256">f6e5d4c3b2a1</hash> </hashes> </app> </reference> <reference type="to"> <app> <hashes> <hash type="SHA-256">998877665544</hash> </hashes> </app> </reference> </flow> </flows> </answer> """ root = ET.fromstring(xml_demo) # 存筛选结果 matched_flows = [] for flow in root.findall("./flows/flow"): # 找两个reference节点 ref_from = flow.find("./reference[@type='from']") ref_to = flow.find("./reference[@type='to']") if not (ref_from and ref_to): continue # 找两个SHA-256哈希节点 hash_from_node = ref_from.find("./app/hashes/hash[@type='SHA-256']") hash_to_node = ref_to.find("./app/hashes/hash[@type='SHA-256']") if not (hash_from_node and hash_to_node): continue # 对比哈希值,不相等就存完整flow内容 hash_from = hash_from_node.text.strip() if hash_from_node.text else "" hash_to = hash_to_node.text.strip() if hash_to_node.text else "" if hash_from != hash_to: matched_flows.append(ET.tostring(flow, encoding="unicode")) # 输出结果 for idx, flow_content in enumerate(matched_flows, 1): print(f"第{idx}个哈希不匹配的flow:\n{flow_content}\n")
初学者注意事项
- XPath语法里属性匹配必须加
@前缀,比如[@type='from'],漏写@会找不到目标节点- 不要手动写多层循环逐层找子节点,用find/findall加XPath路径的写法代码量更少,出错概率更低
- 提取节点文本时一定要判断text是否为None,部分空节点的text属性是None,直接调用strip()会报错
内容的提问来源于stack exchange,提问作者Ajay K
相关产品推荐
相关产品推荐

