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

C# 在C中将两个JSON结构合并为一个,c#,json,oop,json.net,C#,Json,Oop,Json.net,我们有两个相似但略有不同的JSON结构。第一个JSON结构用于无地层场景–这适用于measureId“001”和“002”。第二个JSON结构适用于多层–这适用于measureId:003。对于每个testTIN,我们需要将这两个度量组合起来,如预期的JSON结构所示 JSON 1–无地层 JSON 2–多层 预期的JSON 如何将上述两种JSON结构结合起来,得到这种新的JSON结构 C代码 更新 好的推荐信: 除非您真的需要,否则您可以简单地执行一个任务,而无需创建复杂的POCO类。Newt

我们有两个相似但略有不同的JSON结构。第一个JSON结构用于无地层场景–这适用于measureId“001”和“002”。第二个JSON结构适用于多层–这适用于measureId:003。对于每个testTIN,我们需要将这两个度量组合起来,如预期的JSON结构所示

JSON 1–无地层

JSON 2–多层

预期的JSON

如何将上述两种JSON结构结合起来,得到这种新的JSON结构

C代码

更新

好的推荐信:

除非您真的需要,否则您可以简单地执行一个任务,而无需创建复杂的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"
          }
        ]
      }
    }
  ]
}
如果您最初的无地层和多层测量结果实际上已经序列化为JSON结构,您可以使用以下合并设置将它们合并在一起:

// 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; });
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();
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结果存储在某个文件集合中,则可以直接从文件合并,如下所示:

// 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; });
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();
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文件,那么您可以使用将每个对象投影到JObject,然后合并这些对象:

// 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();

Demo fiddle 2。

我想说,您不需要反序列化输入JSON,而是解析它们。所以:1。通过解析方法获取两个JSON的JToken。2.从第二个JToken集合获取度量集合子令牌。3.将其插入第一个度量集合。4.反序列化整个过程。我们有两个相似但略有不同的JSON结构。-您的初始输入是作为JSON还是作为c POCOs?1那么这真的是一个JSON问题,还是一个数据建模问题?2我注意到MeasurementSet_uuMultistrata有一个物业类别不在MeasurementSet_uNostrata中。这对合并有何影响?您可以使用JToken.FromObject将POCO直接序列化为没有中间字符串表示的对象,然后合并这些对象。@Lijo-但如果不是JSON问题,则可能需要重新设计域模型,合并MeasurementSet_uNostrata和MeasurementSet_uMultistrata,并将度量转化为度量类型的多态集合。
// 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();