是否有一个库(首选C#)来解决我称为多级层叠JSON的问题?
这是我的意思的示例: (Pseudocode / 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
在对需求进行了更多思考之后,我看到了更复杂的示例永远无法按原样工作。例如,级联功能将无法知道某个电话号码是否已被修改,或者它是否是新的。为了使其工作,每个子实体都应具有唯一的标识符。
使用出色的JSON.NET库,这非常容易。此方法将对象与具有字符串,数字或对象的属性组合在一起。
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(); }
结果,给出您的示例:
{ "firstName": "Albert", "lastName": "Smith", "phone": "12345" }
通过将该解决方案调整为递归工作,可以合并子对象。下面的示例将符合您的预期结果(数组除外)。您将能够JArray以类似于合并对象(JObject)的方式轻松扩展此解决方案以合并数组()。
JArray
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; } }