Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Merge two JTokens into one

Tags:

json

c#

json.net

How can I merge these two JTokens into one single JToken. This sounds like it should be simple, but can't get my way around it.

{
  "data":[
  {
      "ID":"53a1862000404a304942546b35519ba3",
      "name":"Private Approval Process: Draft Document CPL",
      "objCode":"ARVPTH"
  }]
}

{
"data":[
  {
      "ID":"53a1838200401324eb1ec66562e9d77d",
      "name":"Private Approval Process: Draft Document CPL",
      "objCode":"ARVPTH"
  }]
}

Thanks for the help!

This is what I have tried so far:

I started by assigning the first object to a variable Jtoken pageOne then, I tried concatenating it into a second variable JToken allPages. I have a loop that brings back multiple pages each with three fields. The final goal is to grab each page and create a big JToken with all of the pages in it.

something like this:

for (int page = 0; page <= recCount; page += 2000)
{
 //Get data
 pageOne = getJsonData();
 allPages.Concat(pageOne);
}
return allPages;
like image 792
JoseStack Avatar asked Jun 10 '16 20:06

JoseStack


2 Answers

You can use JContainer.Merge(Object, JsonMergeSettings) to merge one JObject onto another. Note that JsonMergeSettings.MergeArrayHandling gives control over how arrays are merged. From the MergeArrayHandling Enumeration documentation, the possible merge options are:

Concat   0   Concatenate arrays.
Union    1   Union arrays, skipping items that already exist.
Replace  2   Replace all array items.
Merge    3   Merge array items together, matched by index. 

Thus merging using MergeArrayHandling.Concat as follows, where allPages and pageOne are both of type JContainer (or a subclass, such as JObject):

JContainer allPages = null;
var settings = new JsonMergeSettings { MergeArrayHandling = MergeArrayHandling.Concat };
for (int page = 0; page <= recCount; page += 2000)
{
    //Get data
    var pageOne = (JContainer)getJsonData(page);
    if (allPages == null)
        allPages = pageOne;
    else
        allPages.Merge(pageOne, settings);
}
return allPages;

gives:

{
  "data": [
    {
      "ID": "53a1862000404a304942546b35519ba3",
      "name": "Private Approval Process: Draft Document CPL",
      "objCode": "ARVPTH"
    },
    {
      "ID": "53a1838200401324eb1ec66562e9d77d",
      "name": "Private Approval Process: Draft Document CPL",
      "objCode": "ARVPTH"
    }
  ]
}

While merging using Replace gives:

{
  "data": [
    {
      "ID": "53a1838200401324eb1ec66562e9d77d",
      "name": "Private Approval Process: Draft Document CPL",
      "objCode": "ARVPTH"
    }
  ]
}

If your variables are of type JToken you will need to cast them to JContainer. (JSON primitives that are not containers cannot be merged.)

JsonMergeSettings.MergeNullValueHandling gives control over whether to merge or ignore null values, as required.

like image 140
dbc Avatar answered Oct 24 '22 15:10

dbc


You could merge it like that (or if you had it had it in an array or list you could make a linq group by query for example over the ID property, that would be likewise effective).

  var data1 =  JObject.Parse(@"{
           'data':[
          {
             'ID':'53a1862000404a304942546b35519ba3',
              'name':'Private Approval Process: Draft Document CPL',
              'objCode':'ARVPTH'
          }]
        }");

        var data2 = JObject.Parse(@"{
           'data':[
          {
             'ID':'53a1862000404a304942546b35519ba3',
              'name':'Private Approval Process: Draft Document CPL',
              'objCode':'ARVPTH'
          }]
        }");

        data1.Merge(data2, new JsonMergeSettings
        {
           MergeArrayHandling = MergeArrayHandling.Union
        });

        string json = data1.ToString();
like image 32
marko Avatar answered Oct 24 '22 14:10

marko