使用XSLT1.0对比XML文件差异并输出文本及排查代码问题
XML差异对比XSLT1.0代码的Bug分析
问题场景与Bug表现
需求背景
初始文件file1包含大量带子节点的网络节点,修改后保存为file2,需要用XSLT1.0实现以下功能:
- 检查
file2中新增或删除的key及对应值 - 检查每个key的值是否发生变更
- 在输出中标记差异,并关联每个差异对应的顶级父节点
示例文件
File 1
<node> <node key="Network1"> <node key="@IP" value="65.12.30.20"/> <node key="@MAC" value="62-42-85-74-21"/> <node key="PortNumber" value="12000"/> <node key="Location"> <node key="House" value="Blue"/> <node key="Room" value="Green"/> <node key="Office" value="IT"/> </node> </node> <node key="Network2"> <node key="@IP" value="15.58.12.36"/> <node key="@MAC" value="85-02-14-52-12"/> <node key="PortNumber" value="12000"/> <node key="Location"> <node key="House" value="Blue"/> <node key="Room" value="Yellow"/> <node key="Office" value="IT"/> </node> </node> </node>
File 2
<node> <node key="Network1"> <node key="@IP" value="65.12.30.20"/> <node key="@MAC" value="62-42-85-74-21"/> <node key="PortNumber" value="12001"/> <node key="Location"> <node key="House" value="Blue"/> <node key="Room" value="Green"/> <node key="Office" value="HR"/> <node key="Rack" value="2"/> </node> </node> <node key="Network2"> <node key="@IP" value="15.58.12.36"/> <node key="@MAC" value="14-85-13-74-36"/> <node key="PortNumber" value="12001"/> <node key="Location"> <node key="House" value="Blue"/> <node key="Room" value="Yellow"/> <node key="Office" value="IT"/> <node key="Rack" value="1"/> </node> </node> </node>
Bug表现
当两个XML文件内容完全相同时,现有XSLT代码错误识别出差异:
相同XML示例
<stackoverflow12> <node key="Test"> <node key="keyA"> <node key="A" value="A1"> <node key="Name" value="Tim" /> </node> <node key="A" value="A2"> <node key="Name" value="Tom" /> </node> </node> </node> <node key="Test"> <node key="keyA"> <node key="A" value="A1"> <node key="Name" value="Tim" /> </node> <node key="A" value="A2"> <node key="Name" value="Tom" /> </node> </node> </node> </stackoverflow12>
错误输出
<?xml version="1.0" encoding="UTF-8"?> <node key="Test"> <node key="keyA"> <node key="A" left-value="A1" right-value="A1"/> <node key="A" left-value="A2" right-value="A1"/> </node> </node>
代码问题根源
节点匹配仅依赖
key属性,未处理同层级同key多节点场景
现有代码在匹配左右文件的节点时,仅通过key属性值关联对应节点(比如使用key()函数按@key分组查找)。但当同层级存在多个key值相同的节点时,这种匹配逻辑会错误地将左文件中第N个同key节点,匹配到右文件中第一个同key节点,导致示例中左文件的value="A2"节点被关联到右文件的value="A1"节点,进而被误判为差异。缺少节点的位置或上下文唯一标识
对于同层级的同key多节点,仅靠key属性无法唯一定位对应节点,需要结合节点在同key节点中的位置序号,或者完整的路径上下文来精准匹配左右文件的节点。现有代码忽略了这一关键逻辑,导致节点匹配错位。父节点匹配错位传递到子节点对比
即使子节点的key和value完全一致,由于父节点的匹配错位,子节点的对比逻辑也会继承这种错误,最终输出不存在的差异。
内容的提问来源于stack exchange,提问作者pouce
相关产品推荐
相关产品推荐

