简体   繁体   中英

How to find total number of lowest level of elements in a JSON object?

I have a Json as below

{
  "name": "xxxx",
  "type": "ccc",
  "properties": {
    "serialNumber": {
      "value": "24-66292"
    },
    "documentLinks": {
      "productManuals": {
        "54868484": {
          "url": {
            "value": "xxxx"
          },
          "productName": {
            "value": "R02400"
          }
        }
      },
      "keystringFiles": {
        "60050588": {
          "url": {
            "value": "http://se-s-0010052.de.abb.com/stage/wc/!control.controller?action=view_document&doc_id=60050588"
          },
          "name": {
            "value": "24-66292_160.kxt"
          },
          "fileSize": {
            "value": 0.87
          },
          "addedDate": {
            "value": "2012-01-19"
          },
          "addedBy": {
            "value": "Loader"
          }
        }
      }
    }
  },
  "variables":{
   "temperature" :{
     "dataType": "number"
   },
   "modes" :{
     "normal":{
      "dataType": "string"
     },
     "fast":{
      "dataType": "string"
     }
   }
  }
}

I need to count the total number of elements in this excluding the root level elements. In this example it's like under "properties" below are the number of elements

  1. serialNumber
  2. documentLinks->productManuals->54868484->url
  3. documentLinks->productManuals->54868484->productName
  4. documentLinks->keystringFiles->60050588->url
  5. documentLinks->keystringFiles->60050588->name
  6. documentLinks->keystringFiles->60050588->fileSize
  7. documentLinks->keystringFiles->60050588->addedDate
  8. documentLinks->keystringFiles->60050588->addedBy

Under "variables"

  1. temperature
  2. modes->normal
  3. modes->fast

Hence total number of elements is

8+3 = 11

I was trying multiple things as below, but I am not able to find the best logic which serves the purpose.

var ob = JObject.Parse(json);
var propCount = JObject.Parse(json).Root
                .SelectTokens("properties")
                .SelectMany(t => t.Children().OfType<JProperty>().Select(p => p.Name))
                .ToArray();
            var varCount = JObject.Parse(json).Root
                .SelectTokens("variables")
                .SelectMany(t => t.Children().OfType<JProperty>().Select(p => p.Name))
                .ToArray();
            int propCount = 0;
            int variableCount = 0;
            foreach (var prop in propCount)
            {
                propCount += ob["properties"][prop].Children().Count();
            }
            foreach (var variable in varCount)
            {
                variableCount += ob["variables"][variable].Children().Count();
            }
            var total = propCount + variableCount;

I think, based on what I understand, you have 11. You're missing properties->serialNumber in your count

private int GetLowestLevelCount(JToken obj)
{
  int counter = 0;
  if (obj.HasValues) // Checks if token has children. 
  {
     foreach (var children in obj.Children())
     {
         counter += GetLowestLevelCount(children);
     }

  }
  else // Lowest-level elem. 
  {
     counter +=1;
  }
  return counter;
}

Use:

var ob = JObject.Parse(json);
var mainKeys = ob.Children().Select(x => ((JProperty)x).Name);
int lowestLevel = 0;
foreach (var mainKey in mainKeys)
{
    var a = ob[mainKey];
    if (a.HasValues) //Don't bother with top-level elements 
    {
        foreach (var c in a.Children())
        {
            lowestLevel += GetLowestLevelCount(c);
        }

    }
}
Console.WriteLine(lowestLevel);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM