web-dev-qa-db-ja.com

2つのjsonオブジェクトの違いを見つける

2つのjsonオブジェクトの違いを比較して見つけるのに役立つライブラリが.Netにありますか? JavaScriptで利用できるいくつかのソリューションを見つけましたが、C#には興味深いものはありません。私の質問のポイントは、比較に基づいて、何らかの方法で変更がマークされたjsonを作成することです。ユーザーが変更の場所を確認できるようにします。

22
Steve Macculan
using Microsoft.XmlDiffPatch;
using Newtonsoft.Json;

各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;
    }
}
14
weston

私はあなたの例のものとは異なる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つのJSONオブジェクトを作成するために JSON.NET を使用してから、ツリーを再帰的にループし、各ノードを比較して、ノードが存在するかどうかを確認します。

3
BanksySan

ここに行く最善の方法は、newtonsoft jsonを使用してオブジェクトを作成することだと思います。 http://www.nuget.org/packages/newtonsoft.json/

したがって、同じタイプの2つのオブジェクトがあり、それらを簡単に比較してマークを付けることができます。

0
Pratap Das
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;
}
0
Victor Cánovas