找出两个json对象之间的差异

时间:2013-10-29 19:09:23

标签: c# json diff

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

6 个答案:

答案 0 :(得分:13)

using Microsoft.XmlDiffPatch;
using Newtonsoft.Json;

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

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

答案 1 :(得分:5)

我使用了不同于您示例中的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);
    }

答案 2 :(得分:3)

我认为最好的办法是使用JSON.NET创建两个JSON对象,然后递归遍历树,比较每个节点,看它是否存在并且在你去的时候是相等的。

答案 3 :(得分:0)

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

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

答案 4 :(得分:0)

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

答案 5 :(得分:0)

我想回答这个问题为时已晚,希望您那时能找到解决方案!

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

JSON 1

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

JSON 2

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

用法


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

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

结果

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

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