shab
shab

Reputation: 999

how to get all the array values for a given descendant in a Json

    {
  "hasLoadMore": true,
  "groups": [
    {
      "order": 0,
      "title": "string",
      "total": 0,
      "dateFormat": "string",
      "messages": [
        {
          "commsId": 0,
          "commsDirectionCode": "string",
          "commsReasonCRSNN": 0,
          "commsDeliveryChannelCDCHN": "string",
          "commsDeliveryStateCode": "string",
          "commsDeliveryDttm": "2017-02-14T02:20:52.836Z",
          "commsSuccessFlag": true,
          "commsCode": "string",
          "commsName": "string",
          "commsRankingNumb": 0,
          "customerGrainCUSGN": 0,
          "productItemCode": "string",
          "sourceApplBAPPN": 0,
          "sourceCommsRefn": "string",
          "parentCommsId": 0,
          "campaignDttm": "2017-02-14T02:20:52.836Z",
          "campaignCode": "string",
          "campaignName": "string",
          "contentValidStartDttm": "2017-02-14T02:20:52.836Z",
          "contentValidEndDttm": "2017-02-14T02:20:52.836Z",
          "trackingCode": "string",
          "headlineDisplayText": "string",
          "contentDisplayText": "string",
          "topic": "string",
          "topicIconClass": "string",
          "contentTemplateId": 0,
          "contentTemplateVersNumb": 0,
          "archiveDate": "2017-02-14T02:20:52.836Z",
          "commsParameters": [
            {
              "commsId": 0,
              "paramSeqNumb": 0,
              "paramText": "string",
              "paramValue": "string"
            }
          ],
          "contentTemplateParameters": [
            {
              "commsId": 0,
              "paramSeqNumb": 0,
              "paramText": "string",
              "paramValue": "string"
            }
          ],
          "callToAction": [
            {
              "displayText": "string",
              "uri": "string"
            }
          ],
          "isFlagged": true,
          "isSeen": true,
          "isRead": true,
          "isActioned": true
        }
      ]
    }
  ]
}

my json is above , now i have multiple 'callToActions' array in the above json and want to collect all of them and compare with a table.

what i am doing is below:

 {

        string content = Context.Response.Content.ReadAsStringAsync().Result;

        var resultObjects = AllChildren(JObject.Parse(content))
        .First(c => c.Type == JTokenType.Array && c.Path.Contains(decendant))
        .Children<JObject>();
        JArray responseList = new JArray();
        foreach (JObject result in resultObjects)
        {
           responseList.Add(result);

        }
        CompareObjectToTable(responseList, table);

    }

     private static IEnumerable<JToken> AllChildren(JToken decendant)
    {
        foreach (var c in decendant.Children())
        {
            yield return c;
            foreach (var cc in AllChildren(c))
            {
                yield return cc;
            }
        }
    }

But it will only give me the "First" array encountered but i want to gather all the array(multiple) with same descendant.Here descendant i want is callToActions

Upvotes: 1

Views: 4096

Answers (1)

dbc
dbc

Reputation: 117046

Rather than hand-coding your own method to recursively descend the JToken hierarchy, you can use the built-in methods JContainer.DescendantsAndSelf() or JToken.SelectTokens() to do it for you.

Using the first approach, you would do:

var root = (JContainer)JToken.Parse(content);
var descendant = "callToAction";
var query = root
    // Recursively descend the JSON hierarchy
    .DescendantsAndSelf()
    // Select all properties named descendant
    .OfType<JProperty>()
    .Where(p => p.Name == descendant)
    // Select their value
    .Select(p => p.Value)
    // And filter for those that are arrays.
    .OfType<JArray>();

And using the second approach:

var root = JToken.Parse(content);
var descendant = "callToAction";
var query = root
    // Recursively descend the JSON hierarchy using the JSONpath recursive descent operator "..", and select the values of all properties named descendant
    .SelectTokens(string.Format("..{0}", descendant))
    // And filter for those that are arrays.
    .OfType<JArray>();

Note that I am using the JSONPath recursive descent operator ".." to descend the hierarchy. Json.NET's SelectTokens() method supports JSONPath query syntax which is somewhat similar to XPath.

Now, it's not clear from your question whether responseList should be an array of arrays of results, or a flat array of results. To create an array of arrays, just do:

var responseList = new JArray(query);

To create a flattened array, do:

var responseList = new JArray(query.SelectMany(a => a));

Sample fiddle.

Upvotes: 3

Related Questions