最新要闻
- 穷人入侵TikTok直播间:躺着就能赚钱 真爽
- 焦点热讯:为了帮梅西赢球 我敲了一晚上的电子木鱼
- 环球速递!2022贺岁档总票房突破4亿!《阿凡达2》势不可挡 最快破亿
- 快播:雷军运气爆棚:在小米手机官方活动 中奖一台小米13
- 世界资讯:小米音质最好智能音箱!小米Sound Pro开箱图赏
- 小米首款万兆路由发布:1799元
- 天天速递!只要699元!小米旗舰降噪耳机Buds 4发布:HiFi音质
- 小米8款新品价格汇总:3999元的小米13爱不爱?
- 全球新资讯:雷军:只有两家做双尺寸双高端 一家是苹果 一家是小米
- 小米13正式亮相:金属直边 继续对标iPhone!
- 今亮点!3999元起!小米13正式发布:黄金尺寸小屏、满血徕卡镜头
- 不涨价 小米13价格良心了:顶配12+512GB还便宜200元
- 全球微动态丨小米13 Pro正式亮相:中框仅仅3.2毫米!科技纳米皮手感无敌
- 全球信息:Intel显卡驱动即将大更新!DX9、DX11老游戏有惊喜
- 环球快资讯:MIUI 14“剃刀计划”砍向应用臃肿:微信文件重复存储问题终于解决
- 全球快看点丨全新界面 系统大幅精简!MIUI 14正式发布
广告
手机
iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
- 警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- 男子被关545天申国赔:获赔18万多 驳回精神抚慰金
- 3天内26名本土感染者,辽宁确诊人数已超安徽
- 广西柳州一男子因纠纷杀害三人后自首
- 洱海坠机4名机组人员被批准为烈士 数千干部群众悼念
家电
Python 基于xml.etree.ElementTree实现XML对比
(相关资料图)
测试环境
Python 3.6
Win10
代码实现
#!/usr/bin/env python 3.4.0#-*- encoding:utf-8 -*-__author__ = "shouke"import xml.etree.ElementTree as ETdef compare_xml_node_attributes(xml_node1, xml_node2): result = [] node1_attributes_dict = xml_node1.attrib node2_attributes_dict = xml_node2.attrib for attrib1, value in node1_attributes_dict.items(): value2 = node2_attributes_dict.get(attrib1) if value == value2: node2_attributes_dict.pop(attrib1) else: if value2: attrib2 = attrib1 node2_attributes_dict.pop(attrib2) else: attrib2 = "不存在" result.append("结点1属性:{attrib1} 值:{value1},结点2属性:{attrib1} 值:{value2}".format(attrib1=attrib1 or "不存在", value1=value or "不存在", attrib2=attrib2, value2=value2 or "不存在")) for attrib2, value2 in node2_attributes_dict.items(): result.append("结点1属性:{attrib1} 值:{value1},结点2属性:{attrib1} 值:{value2}".format(attrib1="不存在", value1="不存在", attrib2=attrib2, value2=value2)) return resultdef compare_xml_node_children(xml_node1, xml_node2, node1_xpath, node2_xpath): def get_node_children(xml_node, node_xpath): result = {} for child in list(xml_node): if child.tag not in result: result[child.tag] = [{"node":child, "xpath": "%s/%s[%s]" % (node_xpath, child.tag, 1)}] else: result[child.tag].append({"node":child, "xpath": "%s/%s[%s]" % (node_xpath, child.tag, len(result[child.tag])+1)}) return result result = [] children_of_node1_dict = get_node_children(xml_node1, node1_xpath) children_of_node2_dict = get_node_children(xml_node2, node2_xpath) temp_list1 = [] temp_list2 = [] for child_tag, child_node_list in children_of_node1_dict.items(): second_child_node_list = children_of_node2_dict.get(child_tag, []) if not second_child_node_list: # 获取xml1中比xml2中多出的子结点 for i in range(0, len(child_node_list)): temp_list1.append("%s/%s[%s]" % (node1_xpath, child_node_list[i]["node"].tag, i+1)) continue for first_child, second_child in zip(child_node_list, second_child_node_list): result.extend(compare_xml_nodes(first_child["node"], second_child["node"], first_child["xpath"], second_child["xpath"])) # 获取xml2中对应结点比xml1中对应结点多出的同名子结点 for i in range(len(child_node_list), len(second_child_node_list)): temp_list2.append("%s/%s[%s]" % (node2_xpath, second_child_node_list[i]["node"].tag, i+1)) children_of_node2_dict.pop(child_tag) if temp_list1: result.append("子结点不一样:xml1结点(xpath:{xpath1})比xml2结点(xpath:{xpath2})多了以下子结点:\n{differences}".format (xpath1=node1_xpath, xpath2=node2_xpath, differences="\n".join(temp_list1))) # 获取xml2比xml1中多出的子结点 for child_tag, child_node_list in children_of_node2_dict.items(): for i in range(0, len(child_node_list)): temp_list2.append("%s/%s[%s]" % (node1_xpath, child_node_list[i]["node"].tag, i+1)) if temp_list2: result.append("子结点不一样:xml1结点(xpath:{xpath1})比xml2结点(xpath:{xpath2})少了以下子结点:\n{differences}".format (xpath1=node1_xpath, xpath2=node2_xpath, differences="\n".join(temp_list2))) return resultdef compare_xml_nodes(xml_node1, xml_node2, node1_xpath="", node2_xpath=""): result = [] # 比较标签 if xml_node1.tag != xml_node2.tag: result.append("标签不一样:xml1结点(xpath:{xpath1}):{tag1},xml2结点(xpath:{xpath2}):{tag2}".format (xpath1=node1_xpath, tag1=xml_node1.tag, xpath2=node2_xpath, tag2=xml_node2.tag)) # 比较文本 if xml_node1.text != xml_node2.text: result.append("文本不一样:xml1结点(xpath:{xpath1}):{text1},xml2结点(xpath:{xpath2}):{text2}".format (xpath1=node1_xpath, tag1=xml_node1.text or "", xpath2=node2_xpath, tag2=xml_node2.text or "")) # 比较属性 res = compare_xml_node_attributes(xml_node1, xml_node2) if res: result.append("属性不一样:xml1结点(xpath:{xpath1}),xml2结点(xpath:{xpath2}):\n{differences}".format (xpath1=node1_xpath, xpath2=node2_xpath, differences="\n".join(res))) # 比较子结点 res = compare_xml_node_children(xml_node1, xml_node2, node1_xpath, node2_xpath) if res: result.extend(res) return resultdef compare_xml_strs(xml1_str, xml2_str, mode=3): """ @param: mode 比较模式,预留,暂时没用。目前默认 xml 子元素如果为列表,则列表有序列表,按序比较 """ root1 = ET.fromstring(xml1_str.strip()) root2 = ET.fromstring(xml2_str.strip()) return compare_xml_nodes(root1, root2, "/%s" % root1.tag, "/%s" % root2.tag)
测试运行
xml_str1 = """ 1 2008 141100 4 2011 59900 68 2011 13600 """xml_str2 = """ 1 2008 141100 4 2011 59900 68 2011 13600 """xml_str3 = """ 1 unknow sz 2 unknown 3 unknown other addr """xml_str4 = """ unknow sz unknown other addr """if __name__ == "__main__": res_list = compare_xml_strs(xml_str1, xml_str2) if res_list: print("xml1和xml2不一样:\n%s" % "\n".join(res_list)) else: print("xml1和xml2一样") res_list = compare_xml_strs(xml_str3, xml_str4) if res_list: print("xml3和xml4不一样:\n%s" % "\n".join(res_list)) else: print("xml3和xml4一样")
运行结果
xml1和xml2一样xml3和xml4不一样:子结点不一样:xml1结点(xpath:/data/class[1])比xml2结点(xpath:/data/class[1])多了以下子结点:/data/class[1]/rangk[1]属性不一样:xml1结点(xpath:/data/class[2]/book[2]),xml2结点(xpath:/data/class[2]/book[2]):结点1属性:price 值:15,结点2属性:price 值:16子结点不一样:xml1结点(xpath:/data/class[2])比xml2结点(xpath:/data/class[2])多了以下子结点:/data/class[2]/rangk[1]子结点不一样:xml1结点(xpath:/data/class[2])比xml2结点(xpath:/data/class[2])少了以下子结点:/data/class[2]/addr[1]
-
Python 基于xml.etree.ElementTree实现XML对比
测试环境Python3 6Win10代码实现 ! usr bin envpython3 4 0 -*-encoding:utf-8-*-__author__=& 39;sho
来源: Python 基于xml.etree.ElementTree实现XML对比
天天微资讯!飞链云智能机器人-基于ChatGPT的有趣问答
穷人入侵TikTok直播间:躺着就能赚钱 真爽
焦点热讯:为了帮梅西赢球 我敲了一晚上的电子木鱼
环球速递!2022贺岁档总票房突破4亿!《阿凡达2》势不可挡 最快破亿
GPU CPU向量加法时间测试
快播:雷军运气爆棚:在小米手机官方活动 中奖一台小米13
世界资讯:小米音质最好智能音箱!小米Sound Pro开箱图赏
Windows OpenGL 图像透明度调节
焦点热文:异步批处理教程
小米首款万兆路由发布:1799元
天天速递!只要699元!小米旗舰降噪耳机Buds 4发布:HiFi音质
小米8款新品价格汇总:3999元的小米13爱不爱?
全球新资讯:雷军:只有两家做双尺寸双高端 一家是苹果 一家是小米
小米13正式亮相:金属直边 继续对标iPhone!
今亮点!3999元起!小米13正式发布:黄金尺寸小屏、满血徕卡镜头
不涨价 小米13价格良心了:顶配12+512GB还便宜200元
全球微动态丨小米13 Pro正式亮相:中框仅仅3.2毫米!科技纳米皮手感无敌
焦点消息!ELK+FileBeat日志分析系统
快看点丨差错控制
全球信息:Intel显卡驱动即将大更新!DX9、DX11老游戏有惊喜
环球快资讯:MIUI 14“剃刀计划”砍向应用臃肿:微信文件重复存储问题终于解决
全球快看点丨全新界面 系统大幅精简!MIUI 14正式发布
【世界聚看点】使webworker中支持使用import导入模块——threads.js
世界速看:说人话系列:DOM(Document Object Mode)究竟是怎么来的呢?
环球快报:俞敏洪称不敢进高档美发店:一顿好酒肉没有了 心疼
当前热点-达尔文错了?螃蟹竟在地球上出现了5次
全球新资讯:时间轮 (史上最全)
【天天聚看点】雷军晒小米13生产过程 由小米智能工厂全自动化装配
百事通!Intel独立显卡不做了?掌门人一句话 放心了!
长安深蓝SL03宣布涨价:预计上调2000元-8000元
环球快讯:沉船捞出165年前牛仔裤80万卖出:更有数不清的黄金
SpringMVC执行流程
全球快资讯丨任务调度系统-业务线资源隔离
天天微速讯:echarts设置暂无数据
老版本微博下线倒计时!新版已无法返回老版本
舒适降噪的天花板 索尼WH-1000XM5耳机跌破2000元
全球视点!苹果把果链撤出中国?难度可是地狱级的
天天滚动:SQLyog连接MYSQL时报错 Client does not support authentication protocol requested
世界快报:小米发布米家智能小厨宝7L S1:2000W速热、1年省电100度
播报:男子将手机改装成“偷拍神器”:摄像头改到耳机插孔 赚了30万
世界资讯:我迟早被这些AI绘画笑死
世界快报:买不到抗原检测试剂盒怎么办?不要慌
重点聚焦!Intel A750显卡新驱动性能实测:《CS:GO》帧数飙升79%
公众号附件怎么添加?还在用阅读原文的方式来添加吗,你已经落伍啦,现在大家都在用这个新方法,不仅方便还省事!
TabControl控件的简单使用-添加tab
【全球时快讯】Python爬虫实战,requests+xlwt模块,爬取螺蛳粉商品数据(附源码)
环球微速讯:Linux笔记03: Linux常用命令_3.3文件操作命令
新资讯:canvas分享
全球今头条!推特重推蓝V认证服务 苹果用户得多交3美元!马斯克也无能为力
每日焦点!三星S23 Ultra关键参数确定:首发高频版第二代骁龙8、祖传25W快充
童年记忆的黄桃罐头为啥突然火了?专家建议不要盲目囤
世界今头条!【2023最新B站评论爬虫】用python爬取上千条哔哩哔哩评论
【世界快播报】刘强东称新冠比感冒还轻微!王石也发声:只有鼻子不舒服 10天转阴
全球今亮点!再见C罗!C罗赛后痛哭:葡萄牙0-1摩洛哥 非洲球队首进4强
世界杯英法大战结束!法国2-1淘汰英格兰 晋级四强
中国市场已合资30年!又一车企资不抵债:销量暴跌
全球观速讯丨中国车企在俄罗斯销量飙升:市占率超1/3 主打中高端
每日消息!uniapp+unicloud开发微信小程序流程
焦点快看:清理备用内存 - 解决方案(备用内存占用过高且不自动释放)--九五小庞
天天日报丨Blazor和Vue对比学习(进阶.路由导航四):路由传参
王冰冰反向操作:戴摩洛哥围巾 希望葡萄牙获胜
今日看点:老黄怎么看?这张RTX 4090卖到了10万块 有钱也不一定买到:EVGA绝版货
东北市民网购宠物猪收到已冻僵 网友唏嘘:一个敢买一个敢发
【环球新要闻】从 695. 岛屿的最大面积 入手深度优先搜素DFS
快资讯丨用户重复注册分析-多线程事务中加锁引发的bug
【焦点热闻】PTA作业6-8电信系列总结
环球要闻:C#中的WebAPI
专为AR/VR打造!苹果全新操作系统名为xrOS:有专属应用商店 最早明年推出
全球看点:高校花2.4亿把教学课堂搬到了海上 网友羡慕不已
2022-6.824-Lab2:Raft
007爬虫之requests模块进阶
全球今日讯!攻防世界-unseping(序列化,Bash shell)
全球观速讯丨《暗黑破坏神4》赛季通行证需氪金购买 暴雪重申:不会充钱就变强
JavaScript:this指针
20点狂欢:淘宝每满200减30、天猫/京东每满300减40
厂家称黄桃罐头没药效 网友调侃:黄桃罐头为何成东北人疯狂膜拜的神物
全球看点:验证jenkins自动化部署
世界速读:首个进入太空的人类 宇航员加加林个人档案已解密:34岁死于空难
天天即时看!女生高铁录乐器考试被打断:工作人员知道情况后特意给换了地方
2021冬--简单描述时间复杂度
PDF转图片
Python实战案例,tkinter+random模块,实现课堂随机抽选提问并语音播报学生姓名
世界关注:将近30万人预约!有米粉要当小米13 Pro钉子户
每日观察!86寸4K巨屏!小米EA Pro 86电视今日开售 5999元
比Zen4还火 AMD游戏神U锐龙7 5800X3D史低2199元(首发3099)
MIUI 14花宠摆件上线!米粉:小时候的QQ农场又回来了
每日快报!刘强东分享抗新冠经验:比感冒还轻微 京东将开通热线帮助员工
Windows OpenGL ES 图像透明度
热门看点:我“采访”了 ChatGPT
观察:Blazor和Vue对比学习(进阶.路由导航二):布局(母版/嵌套)
世界简讯:WPF内嵌Http协议的Server端
造车大战中360赢麻了?周鸿祎大赞自己投资的哪吒汽车
天天快看:整活!MIUI 14桌面大变:支持图标自定义调整
当前速读:post表单数据格式完全解析multipart/form-data(C#实现)
队列之王: Disruptor 原理、架构、源码 一文穿透
每日视讯:Python如何导入自定义模块?
环球通讯!进制转换和计算机存储规则
SpringBoot整合Swagger2在线文档
迷惑!大妈凌晨骑车撞上路边停放车辆:怒斥司机不开车灯