XML文件的差异工具?

软件推荐 视窗 xml 差异
2021-11-02 21:39:40

我正在寻找一个基于 Windows 的差异工具,它可以向我展示两个 XML 文件之间的差异,但它是基于树的,而不是基于行的
即,如果一个部分已移动到文件中完全不同的位置,则不应报告差异。
这两个文件应报告为“相同”:

<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>

当然,所有的差异都应该被标记出来,最好是在并排视图中,用指示器或线条连接不同的部分。

免费会很好。
可选地忽略名称空间会很好。

4个回答

从技术上讲,XML 是不同的

  • 他们是否有空格
  • 如果顺序不同
  • 他们是否有意见
  • 他们是否有处理指令
  • 如果它们的编码不同
  • 如果它们的命名空间不同

但当然,您可以根据 XML 所没有的语义信息来决定是否忽略它。

Microsoft为此目的开发了XML Diff and Patch 工具,您可以将它集成到您​​自己的应用程序中。

注意:该工具安装为“.NET 代码示例中的 SQLXML Bulkload”,并附带一个XmlDiffView.sln您需要自己编译的 Visual Studio 解决方案。C#和Visual Studio社区版的一些基本编程知识应该没问题。

但是,正如Stack Overflow 上的答案之一所述,它已被编译并在 Bitbucket 上可用。

之后,它带有一个 UI,让您可以选择各种 XML 比较选项:

XmlDiff 用户界面

当我将它应用于您问题的 2 个 XML 时,它会引发异常。那是因为没有定义的命名空间。删除命名空间后,它说:

给定选项的文件相同

关注移动部分的部分应该报告,因为没有区别让我想到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:ItemIdsandmes:ItemShape并将文本更改为Textus. 在 Semantic Merge 中比较以下两个文件,得到如下图像:

语义合并屏幕截图

在此图像中,可以看到由图标指示的移动,M以及由图标指示的文本变化C线条表示不同部分已移动/更改的位置,如果存在差异,则可以实际看到差异。

请注意,即使理解 C# 代码,语义合并也不会严格限制 的相同类名typ__FieldURI,这可能是一个不错的功能,因为 XML 可以包含多个具有相同名称的节点。

Summa summarum: 语义合并可以正确地将 XML 识别为相同(或不同),即使元素移动,如果您可以将 XML 转换为 C# 类结构。

从技术上讲,这些并不相同(至少在 xml 中),顺序确实很重要,除非在模式中明确说明。

xmlstarlet 和普通的基于行的实用程序的组合可以使问题更容易处理。

以下仅比较结构,但可以扩展到查看属性、它们的值和文本

xmlstarlet el snippet1-with-namespaces.xml | sort > structure1.txt

xmlstarlet el snippet2-with-namespaces.xml | sort > structure2.txt

diff structure.txt structure2.txt

在你的代码片段上运行这个之后,差异没有显示出任何差异,但是有一些关于命名空间的错误文本(可以安全地忽略)。

我会推荐一个工具XiMpLe,它是 XML 编辑器的主要工具,但它也能够以一种排列良好的方式比较(和合并)xml 文件。您的示例被比较并评估为相同。还可以选择解析命名空间。

比较结果示例