Ayan
Ayan

Reputation: 115

How to retrieve a specific property from a nested JSON object

I have a nested json object which looks like this

{{
  "id": "99ed8a1a-68fa-4464-b5cb-f116ede0a520",
  "title": "NUnitTestDemo",
  "has_children": true,
  "level": 0,
  "children": [
    {
      "id": "c41764b1-a59a-420b-b06e-9f97f3876e9b",
      "title": "TestScripts",
      "has_children": true,
      "level": 1,
      "children": [
        {
          "id": "cfba3d9e-d305-464d-9154-cdd2efcb5436",
          "title": "SmokeTest",
          "has_children": true,
          "level": 2,
          "children": [
            {
              "id": "b58596fc-aeab-4f20-8a91-85599c08c0fc",
              "title": "TestAdd",
              "has_children": false,
              "level": 3,
              "tag": "mytag,add",
              "property": "Testing Addition of Two numbers",
              "children": []
            },
            {
              "id": "c819746e-25b9-4c84-8fb4-28794c3b2fe4",
              "title": "TestSubtract",
              "has_children": false,
              "level": 3,
              "tag": "mytag,subtract",
              "property": "Testing Subtraction of Two numbers",
              "children": []
            }
          ]
        },
        {
          "id": "7dce76a3-f318-4d49-920c-1d94b3ec9519",
          "title": "SmokeTest1",
          "has_children": true,
          "level": 2,
          "children": [
            {
              "id": "64bf771d-313b-44ce-b910-27945505dada",
              "title": "TestMultiply",
              "has_children": false,
              "level": 3,
              "tag": "mytag,add",
              "property": "Testing Addition of Two numbers",
              "children": []
            },
            {
              "id": "5d810bc0-a9af-4838-b8eb-5fc7c47e910a",
              "title": "TestDivide",
              "has_children": false,
              "level": 3,
              "tag": "mytag,subtract",
              "property": "Testing Subtraction of Two numbers",
              "children": []
            }
          ]
        },
        {
          "id": "8af09935-93fa-4379-9aa4-9f809055d1ea",
          "title": "Sample",
          "has_children": true,
          "level": 2,
          "children": [
            {
              "id": "407944bd-437e-48cd-8af0-bbd2eb376e72",
              "title": "Tests",
              "has_children": true,
              "level": 3,
              "children": [
                {
                  "id": "01223a10-2dda-4e3c-9287-d49b0c08870d",
                  "title": "SmokeTest2",
                  "has_children": true,
                  "level": 4,
                  "children": [
                    {
                      "id": "6e3df5f1-bcca-40a8-9ed5-3eaa74558488",
                      "title": "TestA",
                      "has_children": false,
                      "level": 5,
                      "tag": "mytag,add",
                      "property": "Testing Addition of Two numbers",
                      "children": []
                    },
                    {
                      "id": "0414d2c3-e4c8-4e52-9584-6a9e8516a3e2",
                      "title": "TestB",
                      "has_children": false,
                      "level": 5,
                      "tag": "mytag,subtract",
                      "property": "Testing Subtraction of Two numbers",
                      "children": []
                    }
                  ]
                }
              ]
            }
          ]
        },
        {
          "id": "7dbfcdfe-f6cb-4942-bcc6-3ec899aec674",
          "title": "MyTestFolder",
          "has_children": true,
          "level": 2,
          "children": [
            {
              "id": "16c3a197-824a-4309-bb97-24d454d448f5",
              "title": "MyTestClass",
              "has_children": true,
              "level": 3,
              "children": [
                {
                  "id": "c37f2d67-0db0-49bf-80e0-9e99d7e9d767",
                  "title": "TestC",
                  "has_children": false,
                  "level": 4,
                  "tag": "mytag,add",
                  "property": "Testing Addition of Two numbers",
                  "children": []
                },
                {
                  "id": "a91c8c04-8a60-4872-b990-db9f993ddbe5",
                  "title": "TestD",
                  "has_children": false,
                  "level": 4,
                  "tag": "mytag,subtract",
                  "property": "Testing Subtraction of Two numbers",
                  "children": []
                }
              ]
            }
          ]
        }
      ]
    }
  ]
}}

If you notice at every level there is a "children" array. Now, when I am searching for "MyTestFolder" inside the above mentioned json, it is returning me "null".

My function looks like this. It is written in C# and I am using Newtonsoft.json library.

I am using .NET Core 3.1

public JObject RetrieveSpecifiedJsonObject(string propertyName, JObject jsonObject)
{
    //propertyName is the property to be retrieved
    string title = jsonObject.SelectToken("title").ToString();
    if(title != propertyName)
    {
        JArray childArray = jsonObject.SelectToken("children") as JArray;
        for(int i=0; i<childArray.Count; i++)
        {
            JObject childArrElem = childArray[i] as JObject;
            string arrElemTitle = childArrElem.SelectToken("title").ToString();
            if(arrElemTitle != propertyName)
            {
                RetrieveSpecifiedJsonObject(propertyName, childArrElem);
            }
            else
            {
                return childArrElem;
            }
        }//FOR ENDS
        return null;
    }//IF title != propertyName ENDS
    else
    {
        return jsonObject;
    }
}

I guess it has to be a recursive function. But, not getting what to do. When I am searching.

FYI, I can't search like jsonobject["children"][0]["MyTestFolder"]. I may have to search for any node at any point of time. For that, I need to write a generic function.

Upvotes: 0

Views: 224

Answers (2)

Rafalon
Rafalon

Reputation: 4515

In addition to what JimmyN wrote in his answer, I'd say that you could simplify your recursive function as such (you already check the title property at the top of the function, so you don't need to check it again inside the for loop):

public JObject RetrieveSpecifiedJsonObject(string propertyName, JObject jsonObject)
{
  //propertyName is the property to be retrieved
  string title = jsonObject.SelectToken("title").ToString();
  if(title != propertyName)
  {            
    JArray childArray = jsonObject.SelectToken("children") as JArray;
    for(int i=0; i<childArray.Count; i++)
    {
      JObject childArrElem = childArray[i] as JObject;
      // the following will already check childArray and all of its children
      JObject result = RetrieveSpecifiedJsonObject(propertyName, childArrElem);
      if(result != null)
        return result;
    }//FOR ENDS
    return null;
  }//IF title != propertyName ENDS
  else
  {
     return jsonObject;
  }
}

Upvotes: 0

JimmyN
JimmyN

Reputation: 599

it returns null because this block doesn't do any action with the result from RetrieveSpecifiedJsonObject

if(arrElemTitle != propertyName)
{
   RetrieveSpecifiedJsonObject(propertyName, childArrElem);
}

maybe you should do that:

if(arrElemTitle != propertyName)
{
   var result = RetrieveSpecifiedJsonObject(propertyName, childArrElem);
   if (result != null)
       return result;
}

Upvotes: 3

Related Questions