網站首頁 編程語言 正文
測試環境
Python 3.6
Win10
代碼實現
#!/usr/bin/env python 3.4.0
#-*- encoding:utf-8 -*-
__author__ = 'shouke'
import xml.etree.ElementTree as ET
def 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 result
def 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 result
def 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 result
def 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 = ''' <?xml version = "1.0" encoding="utf-8" ?> <data> <country name="Liechtenstein"> <rangk>1</rangk> <year>2008</year> <gdppc>141100</gdppc> <neighbor name="Austria" direction="E" ></neighbor> <neighbor name="Switzerland" direction="W" ></neighbor> </country> <country name="Singpore"> <rank>4</rank> <year>2011</year> <gdppc>59900</gdppc> <neighbor name="Malaysia" direction="N" ></neighbor> </country> <country name="Panama"> <rank>68</rank> <year>2011</year> <gdppc>13600</gdppc> <neighbor name="Costa Rica" direction="W" ></neighbor> <neighbor name="Colombia" direction="W" ></neighbor> </country> </data> ''' xml_str2 = ''' <?xml version = "1.0" encoding="utf-8" ?> <data> <country name="Liechtenstein"> <rangk>1</rangk> <year>2008</year> <gdppc>141100</gdppc> <neighbor name="Austria" direction="E" ></neighbor> <neighbor name="Switzerland" direction="W" ></neighbor> </country> <country name="Singpore"> <rank>4</rank> <year>2011</year> <gdppc>59900</gdppc> <neighbor name="Malaysia" direction="N" ></neighbor> </country> <country name="Panama"> <rank>68</rank> <year>2011</year> <gdppc>13600</gdppc> <neighbor name="Costa Rica" direction="W" ></neighbor> <neighbor name="Colombia" direction="W" ></neighbor> </country> </data> ''' xml_str3 = ''' <?xml version = "1.0" encoding="utf-8" ?> <data> <class name="computer"> <rangk>1</rangk> <year>unknow</year> <addr>sz</addr> <book name="java programming" price="10" ></book> <book name="python programming" price="10" ></book> </class> <class name="philosophy"> <rangk>2</rangk> <year>unknown</year> <book name="A little history of philosophy" price="15" ></book> <book name="contemporary introduction" price="15" ></book> </class> <class name="history"> <rangk>3</rangk> <year>unknown</year> <addr>other addr</addr> <book name="The South China Sea" price="10" ></book> <book name="Chinese Among Others" price="10" ></book> </class> </data> ''' xml_str4 = ''' <?xml version = "1.0" encoding="utf-8" ?> <data> <class name="computer"> <year>unknow</year> <addr>sz</addr> <book name="java programming" price="10" ></book> <book name="python programming" price="10" ></book> </class> <class name="philosophy"> <year>unknown</year> <addr>other addr</addr> <book name="A little history of philosophy" price="15" ></book> <book name="contemporary introduction" price="16" ></book> </class> </data> ''' 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]
原文鏈接:https://www.cnblogs.com/shouke/p/16975021.html
相關推薦
- 2022-12-12 數組名不等于指針?sizeof()函數求數組大小錯誤問題及解決_C 語言
- 2023-04-02 Python中time庫的使用(日期時間)_python
- 2022-09-18 Go語言實現文件上傳_Golang
- 2022-09-21 Python?Ast抽象語法樹的介紹及應用詳解_python
- 2023-01-03 在C語言中getchar的使用方法和讀取規則講解_C 語言
- 2022-06-19 微信小程序前端如何調用python后端的模型詳解_python
- 2022-07-06 Qt之使用GraphicsView框架實現思維導圖的示例_C 語言
- 2022-08-30 關于Flask高級_內置信號的介紹和兩個小實例
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支