目前,我正在管理一个包含多个XML配置文件的软件。当发布新版本的软件时,有时基本配置文件会发生变化,我们目前在启动时会调用软件KDiff。如果它检测到更改,则会提示用户选择更改。
这种方法的问题在于KDiff是比较程序的行,而不是知道XML的方式(如节点等)
理想情况下,我想以编程方式使用C#中的库(因为我们是一个MS商店),可以对两个XML文件进行Diff:源XML和当前工作XML。
然后使用一些简单的规则将两者合并在一起:
例如,这是“源”XML:
<Configuration>
<Items>
<Item Id="1" Position="true">
<Location X="UseExistingValue" Y="UseExistingValue" Z="UseExistingValue" />
<Something/>
<SomethingElse/>
</Item>
</Items>
</Configuration>
这是“当前工作”XML:
<Configuration>
<Items>
<Item Id="1" Position="false">
<Location X="123" Y="234" Z="345" />
<Another/>
<Something/>
</Item>
</Items>
</Configuration>
合并的版本看起来像:
<Configuration>
<Items>
<Item Id="1" Position="true">
<Location X="123" Y="234" Z="345" />
<Something/>
<SomethingElse/>
</Item>
</Items>
</Configuration>
我查看了MS XML Diff and Patch Tool,它肯定会将文件合并在一起,但不允许我想要定义的编程规则。
XMLUnit for Java devs似乎很有希望,但它的.NET版本似乎不发达,这是不幸的。
任何人对可编写脚本的XML Diff / Merge工具和/或.NET库(付费或免费)有任何建议吗?
感谢。
答案 0 :(得分:21)
经过几天的捣乱,我找到了一个我觉得适合我的解决方案。也许它也适用于其他人。
The MS XML Diff and Patch tool是一个可行的选择。当您针对第二个文件对第一个文件进行Diff时,它会创建一个XML“DiffGram”,列出它在两个XML文件之间检测到的更改。
为了处理我上面列出的所有3条规则,我将这两个文件向一个方向扩展,然后使用Linq-to-XML打开DiffGram文件,并删除所有“添加”和“删除”行。
XNamespace xd = "http://schemas.microsoft.com/xmltools/2002/xmldiff";
var doc = XDocument.Load(_diffGramFile);
doc.Root.DescendantsAndSelf(xd + "add").Remove();
doc.Root.DescendantsAndSelf(xd + "remove").Remove();
然后,我将这个已编辑的diffgram修补(合并)到第一个文件,并创建了一个部分合并的临时文件。这将处理规则1和2。
接下来,我将部分合并的文件与所使用的第一个文件进行了比较。然后打开新的DiffGram并删除所有对“UseExistingValue”的更改引用。
var newdoc = XDocument.Load(_diffGramFile);
newdoc.Root.DescendantsAndSelf(xd + "change")
.Where(x => x.Value == "UseExistingValue").Remove();
并将此编辑过的DiffGram与部分合并的文件合并,该文件负责规则3.将其保存到XML然后根据上面定义的规则生成合并的最终XML。
希望这可以帮助其他人。
提示:安装XmlDiffPatch库后,可以在C:\ Windows \ assembly \ GAC \ XmlDiffPatch \ 1.0.8.28__b03f5f7f11d50a3a \ XmlDiffPatch.dll中找到XmlDiffPatch DLL