C# 查找两个 json 对象之间的差异

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19667085/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 15:34:22  来源:igfitidea点击:

Find differences between two json objects

c#jsondiff

提问by Steve Macculan

Are there any libraries in .Net to help compare and find differences between two json objects? I've found some solutions available for JavaScript, but nothing interesting for C#. The point of my question is to create json with changes marked in some way, based on the comparison. So that the user could see where the changes are.

.Net 中是否有任何库可以帮助比较和查找两个 json 对象之间的差异?我找到了一些适用于 JavaScript 的解决方案,但对 C# 来说没有什么有趣的。我的问题的重点是根据比较创建以某种方式标记更改的 json。以便用户可以看到更改的位置。

回答by BanksySan

I think your best bet is to use JSON.NETto create two JSON objects, then recursively loop through the tree, comparing each node to see if it exists and is equal while you go.

我认为你最好的选择是使用JSON.NET创建两个 JSON 对象,然后递归地遍历树,比较每个节点以查看它是否存在并且在你运行时是否相等。

回答by Pratap Das

I think the best way to go here is to create objects using newtonsoft json.http://www.nuget.org/packages/newtonsoft.json/

我认为最好的方法是使用 newtonsoft json 创建对象。http://www.nuget.org/packages/newtonsoft.json/

So, you will have two objects of the same type, which you can easily compare and mark the differences.

因此,您将拥有两个相同类型的对象,您可以轻松地比较和标记差异。

回答by weston

using Microsoft.XmlDiffPatch;
using Newtonsoft.Json;

Convert each json to xml and use MS XmlDiff libary. Available on nuget. Differences are given in another xml doc which here I write to the console. This is suitable for unit testing for example.

将每个 json 转换为 xml 并使用 MS XmlDiff 库。在nuget可用。差异在另一个 xml 文档中给出,我在这里写到控制台。例如,这适用于单元测试。

public bool CompareJson(string expected, string actual)
{
    var expectedDoc = JsonConvert.DeserializeXmlNode(expected, "root");
    var actualDoc = JsonConvert.DeserializeXmlNode(actual, "root");
    var diff = new XmlDiff(XmlDiffOptions.IgnoreWhitespace |
                           XmlDiffOptions.IgnoreChildOrder);
    using (var ms = new MemoryStream())
    using (var writer = new XmlTextWriter(ms, Encoding.UTF8))
    {
        var result = diff.Compare(expectedDoc, actualDoc, writer);
        if (!result)
        {
            ms.Seek(0, SeekOrigin.Begin);
            Console.WriteLine(new StreamReader(ms).ReadToEnd());
        }
        return result;
    }
}

回答by Bhargava Mummadireddy

I have used different JSON objects than those in your example but it will apply to your case correctly.

我使用的 JSON 对象与您示例中的对象不同,但它将正确适用于您的情况。

private static string GetJsonDiff(string action, string existing, string modified, string objectType)
    {
        // convert JSON to object
        JObject xptJson = JObject.Parse(modified);
        JObject actualJson = JObject.Parse(existing);

        // read properties
        var xptProps = xptJson.Properties().ToList();
        var actProps = actualJson.Properties().ToList();

        // find differing properties
        var auditLog = (from existingProp in actProps
            from modifiedProp in xptProps
            where modifiedProp.Path.Equals(existingProp.Path)
            where !modifiedProp.Value.ToString().Equals(existingProp.Value.ToString())
            select new AuditLog
            {
                Field = existingProp.Path,
                OldValue = existingProp.Value.ToString(),
                NewValue = modifiedProp.Value.ToString(),
                Action = action, ActionBy = GetUserName(),
                ActionDate = DateTime.UtcNow.ToLongDateString(),
                ObjectType = objectType
            }).ToList();

        return JsonConvert.SerializeObject(auditLog);
    }

回答by Victor Cánovas

private IEnumerable<JProperty> JSONCompare(string expectedJSON, string actualJSON)
{
    // convert JSON to object
    JObject xptJson = JObject.Parse(expectedJSON);
    JObject actualJson = JObject.Parse(actualJSON);

    // read properties
    var xptProps = xptJson.Properties().ToList();
    var actProps = actualJson.Properties().ToList();

    // find missing properties
    var missingProps = xptProps.Where(expected => actProps.Where(actual => actual.Name == expected.Name).Count() == 0);

    return missingProps;
}

回答by Amin Mirzapour

I guess it is too late to answer this question and I hope you have found a solution back then!

我想现在回答这个问题为时已晚,我希望您当时已经找到了解决方案!

In case you are here and looking for a light weight library to compares two JSON objects (or practically any serializable entities) You may use the following package, it (currently) uses Newtonsoft.Json JObjects and highlights the differences based on a simple convention (* modified, - removed, + added from/ to the second operand) as shown below.

如果您在这里寻找一个轻量级的库来比较两个 JSON 对象(或几乎任何可序列化的实体)您可以使用以下包,它(当前)使用 Newtonsoft.Json JObjects 并根据简单的约定突出显示差异( * 修改,- 删除,+ 从/添加到第二个操作数),如下所示。

JSON 1

JSON 1

{
  "name":"John",
  "age":30,
  "cars": {
    "car1":"Ford",
    "car2":"BMW",
    "car3":"Fiat"
  }
 }

JSON 2

JSON 2

{
  "name":"John",
  "cars": {
    "car1":"Ford",
    "car2":"BMW",
    "car3":"Audi",
    "car4":"Jaguar"
  }
 }

Usage

用法


 var j1 = JToken.Parse(Read(json1));
 var j2 = JToken.Parse(Read(json2));

 var diff = JsonDifferentiator.Differentiate(j1,j2);

Result

结果

{
  "-age": 30,
  "*cars": {
    "*car3": "Fiat",
    "+car4": "Jaguar"
  }
}

https://www.nuget.org/packages/JsonDiffer

https://www.nuget.org/packages/JsonDiffer