如何在C#中比较XML文件?

11

我知道这方面已经有很多类似的问题,但我找不到能满足我的需求的答案。我需要编写一个应用程序来比较XML文件:有两种类型的比较,第一种是针对两个文件,列出所有的差异;第二种是针对多个XML文件,列出与平均值的所有变化。

我正在寻找一些类、库或API,以帮助我完成这个任务。你能提供一些解决方案吗?

但我不确定是否应该使用DOM还是XPath。有什么建议吗?

编辑:

好的,我已经试图使用XmlDiff工具来完成这个任务,但是对于多个Xml文件来说,解决起来相当困难——我不知道如何使用XmlDiffDiagram来解决50个Xml文件之间的差异。

使用LINQ会更好吗?

3个回答

22

微软的XML Diff和Patch API应该能够很好地工作:

public void GenerateDiffGram(string originalFile, string finalFile,
                       XmlWriter diffGramWriter)
    {
        XmlDiff xmldiff = new XmlDiff(XmlDiffOptions.IgnoreChildOrder |
                                      XmlDiffOptions.IgnoreNamespaces |
                                      XmlDiffOptions.IgnorePrefixes);
        bool bIdentical = xmldiff.Compare(originalFile, finalFile, false, diffGramWriter);
        diffGramWriter.Close();
    }

如果需要,您还可以使用Patch工具比较文件并合并它们:

public void PatchUp(string originalFile, string diffGramFile, string outputFile)
    {
        XmlDocument sourceDoc = new XmlDocument(new NameTable());
        sourceDoc.Load(originalFile);

        using (var reader = XmlReader.Create(diffGramFile))
        {
            XmlPatch xmlPatch = new XmlPatch();
            xmlPatch.Patch(sourceDoc, reader);

            using (var writer = XmlWriter.Create(outputFile))
            {
                sourceDoc.Save(writer);
                writer.Close();
            }
            reader.Close();
        }
    }

你打算如何展示它?听起来需要相当多的工作。 - James Johnson
任务是执行1)两个XML文件的比较和2)多个文件的比较。在2)中,我必须显示数字范围(可能是平均值),以及与平均值的差异(例如,如果所有文件中都有相同的值,除了一个文件),以及字符串的变化(我还不知道如何做)。用户将能够从数据库中选择要进行比较的XML文件。 - Patryk
-1: 我相信这只是一个复制粘贴的示例,但是请您使用 XmlReader.Create 而不是 new XmlTextWriter,并且在那些 XmlReader 实例周围放置 using 块。然后我会点赞。 - John Saunders
@Niloofar,我从NuGet上获取了它。 - Jay Croghan
对我来说工作得很好,但我遇到了与注释相关的错误(即使没有指定XmlDiffOptions.IgnoreComments,它也会忽略注释)。 - Ohad Schneider
显示剩余2条评论

7

如果您只是想比较XML文件而不需要知道差异,可以使用XNode.DeepEquals方法

var xmlTree1 = new XElement("Root",
    new XAttribute("Att1", 1),
    new XAttribute("Att2", 2),
    new XElement("Child1", 1),
    new XElement("Child2", "some content")
);
var xmlTree2 = new XElement("Root",
    new XAttribute("Att1", 1),
    new XAttribute("Att2", 2),
    new XElement("Child1", 1),
    new XElement("Child2", "some content")
);
Console.WriteLine(XNode.DeepEquals(xmlTree1, xmlTree2));

遗憾的是,如果属性顺序不匹配,XNode.DeepEquals会返回false,请尝试交换第二个树的Att1和Att2的顺序。 - Marrt

4

我已经阅读了一些关于LINQ to XML的信息,它非常有前途。为什么没有人投赞成票? - Patryk
这两个文件的XSD是否相同? - Maess
愚蠢的问题:什么是XSD? - Patryk
1
这两个 XML 文件的模式是否相同?XSD 是模式的定义。更简单地说,每个文件的结构是否相同? - Maess
如果你所说的结构是指元素、属性等的顺序,那么这并不是必要的,但很可能会保持相同。 - Patryk
不是命令,而是结构。如果结构将保持相同(相同的架构),那么詹姆斯的答案比我的答案更好。我错误地假设您正在尝试比较来自两个不同模式的XML文件的数据。 - Maess

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接