为了账号安全,请及时绑定邮箱和手机立即绑定

在 C# 中将两个 JSON 结构合二为一

在 C# 中将两个 JSON 结构合二为一

C#
月关宝盒 2022-07-10 16:09:50
我们有两个相似但略有不同的 JSON 结构。第一个 JSON 结构适用于 No Strata 场景——这适用于 measureId “001” 和 “002” 。第二个 JSON 结构用于多层 – 这适用于“measureId”:“003”。对于每个 testTIN,我们需要将这两个测量值结合起来,如预期的 JSON 结构所示。JSON 1 – 无分层{    "testTIN": "123",    "measurements": [{            "measureId": "001",            "value": {                "IsEndToEndReported": true,                "PerformanceMet": 5            }        },        {            "measureId": "002",            "value": {                "IsEndToEndReported": true,                "PerformanceMet": 6            }        }    ]}JSON 2 – 多层{    "testTIN": "123",    "measurements": [       {        "measureId": "003",        "value": {            "strata": [{                    "IsEndToEndReported": true,                    "PerformanceMet": 5,                    "Stratum": "Level1"                },                {                    "IsEndToEndReported": true,                    "PerformanceMet": 6,                    "Stratum": "Level2"                }            ]        }    }   ]}预期的 JSON{    "testTIN": "123",    "measurements": [{            "measureId": "001",            "value": {                "IsEndToEndReported": true,                "PerformanceMet": 5            }        },        {            "measureId": "002",            "value": {                "IsEndToEndReported": true,                "PerformanceMet": 6            }        },        {            "measureId": "003",            "value": {                "strata": [{                        "IsEndToEndReported": true,                        "PerformanceMet": 5,                        "Stratum": "Level1"                    },                    {                        "IsEndToEndReported": true,                        "PerformanceMet": 6,                        "Stratum": "Level2"                    }                ]            }        }    ]}如何获得结合上述两种 JSON 结构的新 JSON 结构?
查看完整描述

2 回答

?
素胚勾勒不出你

TA贡献1827条经验 获得超9个赞

您可以简单地进行联合(除非您确实需要,否则无需创建复杂的 POCO 类)。Newtonsoft 支持合并 JSon 的:


var dataObject1 = JObject.Parse(@"{

            ""testTIN"" : ""123"",

            ""measurements"": [{

                ""measureId"": ""001"",

                ""value"": {

                    ""IsEndToEndReported"": true,

                    ""PerformanceMet"": 5

                }

            },

            {

                ""measureId"": ""002"",

                ""value"": {

                    ""IsEndToEndReported"": true,

                    ""PerformanceMet"": 6

                }

            }

            ]

        }");


        var dataObject2 = JObject.Parse(@"{

        ""testTIN"": ""123"",

        ""measurements"": [

        {

            ""measureId"": ""003"",

            ""value"": {

                ""strata"": [{

                    ""IsEndToEndReported"": true,

                    ""PerformanceMet"": 5,

                    ""Stratum"": ""Level1""

                },

                {

                    ""IsEndToEndReported"": true,

                    ""PerformanceMet"": 6,

                    ""Stratum"": ""Level2""

                }

                ]

            }

        }

        ]

        }");


        dataObject1.Merge(dataObject2, new JsonMergeSettings

        {

            // union array values together to avoid duplicates

            MergeArrayHandling = MergeArrayHandling.Union

        });


        string json = dataObject1.ToString();

这将给出一个输出:


    {

  "testTIN": "123",

  "measurements": [

    {

      "measureId": "001",

      "value": {

        "IsEndToEndReported": true,

        "PerformanceMet": 5

      }

    },

    {

      "measureId": "002",

      "value": {

        "IsEndToEndReported": true,

        "PerformanceMet": 6

      }

    },

    {

      "measureId": "003",

      "value": {

        "strata": [

          {

            "IsEndToEndReported": true,

            "PerformanceMet": 5,

            "Stratum": "Level1"

          },

          {

            "IsEndToEndReported": true,

            "PerformanceMet": 6,

            "Stratum": "Level2"

          }

        ]

      }

    }

  ]

}


查看完整回答
反对 回复 2022-07-10
?
慕容708150

TA贡献1831条经验 获得超4个赞

如果您的初始No Strata和多层测量结果实际上已经序列化为JSON 结构JContainer.Merge(Object, JsonMergeSettings),您可以使用合并设置将它们简单地合并在一起MergeArrayHandling.Concat,如下所示:


// Get the initial measurement JSON measurements as strings.

IEnumerable<string> measturements = GetJsonMeasurements();


// And concatenate them together into a combined `JObject`:

var settings = new JsonMergeSettings { MergeArrayHandling = MergeArrayHandling.Concat };

var json = measturements.Aggregate(new JObject(),

                                   (j, s) => { j.Merge(JObject.Parse(s), settings); return j; });

在这里,我假设测量值已经按"testTIN"值分组。如果没有,这很容易通过在聚合之前将所有结果解析为 aJObject并按值分组来添加"testTIN",如下所示:


var settings = new JsonMergeSettings { MergeArrayHandling = MergeArrayHandling.Concat };

var json = measurements

    .Select(j => JObject.Parse(j))

    .GroupBy(j => (string)j["testTIN"])

    .Select(g => g.Aggregate(new JObject(),

                             (j1, j2) => { j1.Merge(j2, settings); return j1; })

            )

    .ToList();

或者,如果您的 JSON 结果存储在某些文件集合中,您可以直接从文件中合并,如下所示:


var settings = new JsonMergeSettings { MergeArrayHandling = MergeArrayHandling.Concat };

var json = fileNames.Aggregate(new JObject(),

                               (j, s) => 

                               { 

                                   using (var file = File.OpenText(s))

                                   using (var reader = new JsonTextReader(file))

                                   {

                                       j.Merge(JToken.Load(reader), settings);

                                   }

                                   return j; 

                               });

演示在这里摆弄单元测试。


更新


如果您有一个可枚举的对象并希望通过将它们的 JSON 表示合并在一起来创建一个组合的 JSON 文件,您可以将每个对象投影到JObjectusing JObject.FromObject,然后合并它们:


// Get the results

IEnumerable<MeasurementSet__NoStrata> measurements1 = GetNoStrataMeasurements(); // Get no-strata measurements.

IEnumerable<MeasurementSet__MultiStrata> measurements2 = GetMultiStrataMeasurements(); // Get multistrata measurements.


// Combine them into a single enumerable

IEnumerable<object> measurements = measurements1.Cast<object>()

    .Concat(measurements2.Cast<object>());


// Select serialization and merge settings

var serializerSettings = new JsonSerializerSettings

{

    // Put whatever you want here, e.g.

    NullValueHandling = NullValueHandling.Ignore,

};

var mergeSettings = new JsonMergeSettings 

    // Required

    MergeArrayHandling = MergeArrayHandling.Concat,

    // Put whatever you want here, either Ignore or Merge

    // https://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_Linq_MergeNullValueHandling.htm

    MergeNullValueHandling = MergeNullValueHandling.Ignore, // Or Merge if you prefer

};


// Serialize and merge the results

var serializer = JsonSerializer.CreateDefault(serializerSettings);

var json = measurements

    .Select(m => JObject.FromObject(m, serializer))

    .GroupBy(j => (string)j["testTIN"])

    .Select(g => g.Aggregate(new JObject(),

                             (j1, j2) => { j1.Merge(j2, mergeSettings); return j1; })

            )

    // Do we need to remove the `"category"` property?

    // If so do it here.

    .Select(o => { o.Remove("category"); return o; })

    .ToList();

演示小提琴#2在这里。


查看完整回答
反对 回复 2022-07-10
  • 2 回答
  • 0 关注
  • 490 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信