如果节已移到文件中完全不同的位置,则不应报告差异。
这两个文件应报告为“相同”:
<soapenv:Body>
<mes:GetItem>
<mes:ItemShape>
<typ:BaseShape>IdOnly</typ:BaseShape>
<typ:BodyType>Text</typ:BodyType>
<typ:AdditionalProperties>
<typ:FieldURI FieldURI="item:Subject" />
<typ:FieldURI FieldURI="item:Categories" />
</typ:AdditionalProperties>
</mes:ItemShape>
<mes:ItemIds>
<typ:ItemId Id="AAMYAAA="/>
</mes:ItemIds>
</mes:GetItem>
</soapenv:Body>
<soapenv:Body>
<mes:GetItem>
<mes:ItemIds>
<typ:ItemId Id="AAMYAAA="/>
</mes:ItemIds>
<mes:ItemShape>
<typ:BodyType>Text</typ:BodyType>
<typ:BaseShape>IdOnly</typ:BaseShape>
<typ:AdditionalProperties>
<typ:FieldURI FieldURI="item:Categories" />
<typ:FieldURI FieldURI="item:Subject" />
</typ:AdditionalProperties>
</mes:ItemShape>
</mes:GetItem>
</soapenv:Body>
当然,所有差异都应标记出来,最好是在并排视图中用指示器或连接不同部分的线来表示。
免费会很好。
可选地忽略名称空间会很好。
#1 楼
从技术上讲,XML是不同的是否具有空格
如果顺序不同
如果它们具有注释
如果它们具有处理指令与否
如果它们的编码不同
如果它们的名称空间不同
,但是您当然可以基于XML的语义信息来决定是否忽略它
Microsoft为此目的开发了XML Diff and Patch工具,您可以将其集成到自己的应用程序中。
注意:该工具安装为“ SQLXML Bulkload in “ .NET代码示例”,并附带需要自己进行编译的Visual Studio解决方案
XmlDiffView.sln
。 C#和Visual Studio Community Edition的一些基本编程知识应该是可以的。 之后,它提供了一个UI,可让您选择各种XML比较选项:
当我将其应用于您所问问题的2个XML时,它会引发异常。那是由于未定义的名称空间。删除命名空间后,它说:
评论
谢谢。我已对此答案表示赞同,但未将其标记为正确的答案。原因:GUI工具的结果窗口的界面很糟糕:比较两个大型XML文件时,差异窗口的宽度约为3000像素,包含所有相同的XML,并且没有滚动条。然后尝试找出两个55 MB的文件之间的区别;-(我不是Cx程序员,所以我无法适应该程序。
–user416
17年4月3日在12:16
@JanDoggen:是的,我同意,这是非常面向开发人员的。没有编程技能就很难使用它。
–托马斯·韦勒(Thomas Weller)
17年4月3日在12:23
@JanDoggen滚动条是一个很小的条,在窗口的右边缘只有几像素宽。我同意输出不是很好,但是它仍然是一个有用的工具。
– Suncat2000
17年8月3日在13:10
@ThomasWeller +1链接到BitBucket。我进行了编译,但没有运气,无法正常工作。
– Suncat2000
17年8月3日在13:12
#2 楼
专注于应该报告移动部分的部分,因为没有差异,使我想到了http://semanticmerge.com/,它不比较XML文件,而是C#和C代码。并且,由于它了解这些语言,因此能够显示代码是否移动并且未更改。这导致了此问题的另一种解决方法:是否可以将XML转换为C#类,并且然后对结果代码进行语义合并?
如果尚未编写此工具,则一种可能的方法是将每个元素转换为类,并将每个属性(和主体文本)转换为该类中的字符串属性。如果要忽略名称空间,请让您的翻译人员在翻译过程中将其删除。
我翻译了给出的XML示例作为概念证明,并得到了以下内容:
class soapenv__Body {
class mes__GetItem {
class mes__ItemShape {
class typ__BaseShape {
string body="IdOnly";
}
class typ__BodyType {
string body="Textus";
}
class typ__AdditionalProperties {
class typ__FieldURI {
string FieldURI="item:Subject";
}
class typ__FieldURI {
string FieldURI="item:Categories";
}
}
}
class mes__ItemIds {
class typ__ItemId {
string Id="AAMYAAA=";
}
}
}
}
然后我切换了
mes:ItemIds
和mes:ItemShape
并将文本更改为Textus
。在“语义合并”中比较了以下两个文件,并得到了以下图像:由M
图标指示的文本。线条指示不同部分的移动/更改位置,并且可能实际看到它们是否存在差异。请注意,即使理解C#代码,语义合并也不是严格限制在同一类上
C
的名称很不错,因为XML可以包含多个具有相同名称的节点。摘要:即使元素移动,语义合并也可以正确地将XML标识为相同(或不相同),如果可以将XML转换为C#类结构。
评论
只是为了好玩,我尝试移动typ:FieldUri元素,并且语义合并正确地将它们标识为已移动。因此,可以正确检测到顺序,如果需要,您可以跟踪属性的顺序。
– Holroy
15年6月26日在21:36
#3 楼
从技术上讲,它们是不一样的(至少在xml中是这样),顺序很重要,除非在架构中明确指出了这一点。以下内容仅比较结构,但可以扩展为查看属性,它们的值和文本
xmlstarlet el snippet1-with-namespaces.xml | sort > structure1.txt
xmlstarlet el snippet2-with-namespaces.xml | sort > structure2.txt
diff structure.txt structure2.txt
之后在您的代码片段上运行此命令,差异未显示差异,但存在有关名称空间的错误文本(可以忽略)。
#4 楼
我会推荐一个工具XiMpLe,它是XML编辑器的主要工具,但它也能够以一种安排良好的方式比较(和合并)xml文件。您的示例经过比较并评估为相同。还有一个选项也可以解析名称空间。
#5 楼
目前,我正在为自己解决一个非常相似的问题。不幸的是,我没有找到适合我的需要来生成xml比较的svg可视化效果的库。
所以只是为了好玩,并希望找到支持XmlXdiff库的人。
到目前为止,它不是项目符号证明库,仍在建设中,但这是您的示例代码段的结果:
产生此结果的代码:
from XmlXdiff.XReport import DrawXmlDiff
_xml1 = """<frame xmlns:soapenv="sn" xmlns:mes="meas" xmlns:typ="type">
<soapenv:Body>
<mes:GetItem>
<mes:ItemShape>
<typ:BaseShape>IdOnly</typ:BaseShape>
<typ:BodyType>Text</typ:BodyType>
<typ:AdditionalProperties>
<typ:FieldURI FieldURI="item:Subject" />
<typ:FieldURI FieldURI="item:Categories" />
</typ:AdditionalProperties>
</mes:ItemShape>
<mes:ItemIds>
<typ:ItemId Id="AAMYAAA="/>
</mes:ItemIds>
</mes:GetItem>
</soapenv:Body>
</frame>"""
_xml2 = """<frame xmlns:soapenv="sn" xmlns:mes="meas" xmlns:typ="type">
<soapenv:Body>
<mes:GetItem>
<mes:ItemIds>
<typ:ItemId Id="AAMYAAA="/>
</mes:ItemIds>
<mes:ItemShape>
<typ:BodyType>Text</typ:BodyType>
<typ:BaseShape>IdOnly</typ:BaseShape>
<typ:AdditionalProperties>
<typ:FieldURI FieldURI="item:Categories" />
<typ:FieldURI FieldURI="item:Subject" />
</typ:AdditionalProperties>
</mes:ItemShape>
</mes:GetItem>
</soapenv:Body>
</frame>"""
_path1 = '{}\..\..\tests\simple\xml1.xml'.format(getPath())
_path2 = '{}\..\..\tests\simple\xml2.xml'.format(getPath())
_out = '{}\..\..\tests\simple\xdiff.svg'.format(getPath())
with open(_path1, "w") as f:
f.write(_xml1)
with open(_path2, "w") as f:
f.write(_xml2)
x = DrawXmlDiff(_path1, _path2)
x.draw()
x.saveSvg(_out)
评论
免费XML比较工具的可能副本@rrirower是的,但是它在那里关闭了:/ Stack Exchange具有关闭而不是迁移的趋势。
Jan,您是否尝试过Windows上最常见的差异程序(例如WinMerge2011),以查看它们是否具有该功能的选项? (请注意,自上次更新常规WinMerge以来,WinMerge2011进行了许多更新,即使名称暗示相反的意思。)
“报告为'相同'” ...仅当您坚持认为某些标签的顺序无关时,这些XML文件才是“相同”的。对于某些人来说,顺序确实很重要。您需要一个架构或其他信号来指示哪种情况,哪种标记。
@Mast我当前的工作不再需要这个,所以我把它放在了后面。不过,在我可以抽出时间的时候,仍然打算重新查看这篇文章。