C#有用于解析的多级级联JSON库? [英] Does C# have a library for parsing multi-level cascading JSON?

查看:118
本文介绍了C#有用于解析的多级级联JSON库?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有一个图书馆(首选C#)来解决我所说的多级级联的JSON

Is there a library (C# preferred) to resolve what I would call multi-level cascading JSON?

这里是什么,我的意思是一个例子: (伪代码/ C#)

var json1 = @"{
    ""firstName"": ""John"",
    ""lastName"": ""Smith""
    }";

var json2 = @"{
    ""firstName"": ""Albert""
    }";

var json3 = @"{
    ""phone"": ""12345""
    }";

var cascadingJSON = JSON.Cascade(json1, json2, json3);



结果(同行为CSS)

{
    "firstName"": "Albert", /*Overridden*/
    "lastName"": "Smith", /*Inherited*/
    "phone"": "12345"   }"; /*Added*/
}

修改1 - 更复杂的例子

const string json1 =
                @"{
                     ""firstName"": ""John"",
                     ""lastName"": ""Smith"",
                     ""age"": 25,
                     ""address"": 
                     {
                         ""streetAddress"": ""21 2nd Street"",
                         ""city"": ""New York"",
                         ""state"": ""NY"",
                         ""postalCode"": ""10021""
                     },
                     ""phoneNumber"": 
                     [
                         {
                           ""type"": ""home"",
                           ""number"": ""212 555-1234""
                         },
                         {
                           ""type"": ""fax"",
                           ""number"": ""646 555-4567""
                         }
                     ]
                 }";

            const string json2 =
                @"{
                     ""firstName"": ""John2"",
                     ""lastName"": ""robert"",
                     ""age"": 25,
                     ""address"": 
                     {
                         ""state"": ""FL"",
                     },
                     ""phoneNumber"": 
                     [
                         {
                           ""type"": ""fax"",
                           ""number"": ""222 222-2222""
                         },
                         {
                           ""type"": ""iphone"",
                           ""number"": ""111 111-1111""
                         }
                     ]
                 }";

            const string json3 =
                @"{
                     ""firstName"": ""John3"",
                     ""father"": ""guy""
                 }";

            const string expectedResult =
                @"{
                     ""firstName"": ""John3"",
                     ""lastName"": ""robert"",
                     ""age"": 25,
                     ""father"": ""guy"",
                     ""address"": 
                     {
                         ""streetAddress"": ""21 2nd Street"",
                         ""city"": ""New York"",
                         ""state"": ""FL"",
                         ""postalCode"": ""10021""
                     },
                     ""phoneNumber"": 
                     [
                         {
                           ""type"": ""home"",
                           ""number"": ""212 555-1234""
                         },
                         {
                           ""type"": ""fax"",
                           ""number"": ""222 222-2222""
                         },
                         {
                           ""type"": ""iphone"",
                           ""number"": ""111 111-1111""
                         }
                     ]
                 }";



编辑2

在想一个多一点关于我看到更复杂的例子不可能作为工作就是需求之后。级联功能将无法知道是否通过例子,在一定的电话号码已被修改,或者如果它是新的。为了使它工作,每个子实体应该有一个唯一的标识符。

After thinking a bit more about the requirements I see that the more complex example could never work as is. The Cascading function would not be able to know if, by example, a certain phone number has been modified or if it is new one. To make it work, each sub-entity should have a unique identifier.

推荐答案

这是采用出色的超级容易的 JSON.NET库。这种方法结合对象与那些是字符串,数字或对象的属性。

This is super easy using the excellent JSON.NET library. This method combines objects with properties that are are strings, numbers, or objects.

public static string Cascade(params string[] jsonArray)
{
    JObject result = new JObject();
    foreach (string json in jsonArray)
    {
        JObject parsed = JObject.Parse(json);
        foreach (var property in parsed)
            result[property.Key] = property.Value;
    }
    return result.ToString();
}



结果,给出你的例子:

Result, given your example:

{
  "firstName": "Albert",
  "lastName": "Smith",
  "phone": "12345"
}






编辑回应你更新的问题:



通过调整这个解决方案递归调用,您可以合并子对象。下面的例子将匹配您预期的结果(除了阵列)。您将能够轻松地扩展该解决方案合并阵列( JArray )的方式相似,它是如何合并的对象( JObject )。


Edit in response to your updated question:

By adjusting this solution to work recursively, you can merge child objects. The following example will match your expected results (except for the array). You will be able to easily extend this solution to merge arrays (JArray) in a manner similar to how it merges objects (JObject).

public static string Cascade(params string[] jsonArray)
{
    JObject result = new JObject();
    foreach (string json in jsonArray)
    {
        JObject parsed = JObject.Parse(json);
        Merge(result, parsed);
    }
    return result.ToString();
}

private static void Merge(JObject receiver, JObject donor)
{
    foreach (var property in donor)
    {
        JObject receiverValue = receiver[property.Key] as JObject;
        JObject donorValue = property.Value as JObject;
        if (receiverValue != null && donorValue != null)
            Merge(receiverValue, donorValue);
        else
            receiver[property.Key] = property.Value;
    }
}

这篇关于C#有用于解析的多级级联JSON库?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆