Count Number of Elements in JSON string with Json.NET in C#

Go To StackoverFlow.com

10

I have a JSON string that looks like this:

{
"package1": {
    "type": "envelope",
    "quantity": 1,
    "length": 6,
    "width": 1,
    "height": 4
},
"package2": {
    "type": "box",
    "quantity": 2,
    "length": 9,
    "width": 9,
    "height": 9
}
}

I'm using the Json.NET LINQ to JSON functionality to handle my JSON string, but I'm wondering how I can find the total number of nodes/elements/keys (I'm not really sure what to call them) in my string. For example, the above string has package1 and package2 so I'm wondering how I can get it to return the integer 2. Sometimes I might only have one package, in which case, I'd like it to return the integer 1. Other times I might have 20 packages (in that case I'd like it to return 20).

My JObject looks like this:

JObject o = JObject.Parse(myJsonString);

Any ideas? Thanks for any help.

2012-04-03 20:48
by Brent Barbata


19

JObject jObj = (JObject)JsonConvert.DeserializeObject(myJsonString);
int count = jObj.Count;

BONUS:

dynamic jObj = JsonConvert.DeserializeObject(myJsonString);

foreach (var package in jObj)
{
    Console.WriteLine("{0} {1}", package.First.type, package.First.quantity);
}
2012-04-03 20:55
by L.B
Thank you so much! This has been driving me crazy for days. I'll mark it correct in 4 minutes: - Brent Barbata 2012-04-03 20:58
@BrentBarbata Another useful link : - L.B 2012-04-03 21:00
Ha I accepted it before I read the recommended 24-48 hour waiting period. I'm new so I'm still learning. Anyway, thanks again for your help - Brent Barbata 2012-04-03 21:06
@BrentBarbata see the bonus if you can use dynamicL.B 2012-04-03 21:11
The second way works even better for what I'm ultimately trying to do. Thank you a million times - Brent Barbata 2012-04-03 21:20
@BrentBarbata you're welcome - L.B 2012-04-03 21:21


0

Recursive version (count all properties with primitive values)

Came across this question trying to google for a recursive count of JObject values, didn't find many other questions, so figured I'd add what I came up with to this question as well

int CountJTokenProperties(JToken token)
{
    var sum = 0;

    if (token.Type == JTokenType.Object)
    {
        foreach (var child in token.Value<JObject>())
        {
            sum += CountJTokenProperties(child.Value);
        }
    }
    else if (token.Type == JTokenType.Array)
    {
        foreach (var child in token.Value<JArray>())
        {
            sum += CountJTokenProperties(child);
        }
    }
    else
    {
        sum += 1;
    }

    return sum;
}

There might be a better alternative to .Value<JObject>() and .Value<JArray>(), but this seems to be working.

And specifically I wanted this for a nunit test that had variable sample data, and wanted to make sure it deserialized correctly. Decided that an easy way to check would be how many non-default values there were on the C# object, and JsonConvert has that ability:

public int CountNonDefaultProperties(object obj)
{
    // Let JsonConvert do the work of stripping out default values
    var serialized = JsonConvert.SerializeObject(obj, new JsonSerializerSettings
    {
        DefaultValueHandling = DefaultValueHandling.Ignore
    });

    // Recurse into the json structure, which is much simpler than C# Object structure
    var jObj = JObject.Parse(serialized);

    return CountJTokenProperties(jObj);
}

Note that DefaultValueHandling.Ignore keeps default values that are part of arrays, so if you wanted that feature you'd need to count the array items in a different way or something, this activity is left to the reader

https://dotnetfiddle.net/XIZCvh

2018-07-08 18:33
by Thymine


0

With Cinchoo ETL - an open source library, you can do the node count easily with less memory overhead, as it is using streaming approach to parse the input. Hence it can handle large file as well.

string json = @"{
""package1"": {
""type"": ""envelope"",
""quantity"": 1,
""length"": 6,
""width"": 1,
""height"": 4
},
""package2"": {
""type"": ""box"",
""quantity"": 2,
""length"": 9,
""width"": 9,
""height"": 9
}
}";

using (var p = ChoJSONReader.LoadText(json).WithJSONPath("$.*"))
{
    Console.WriteLine(p.Count());
}

Hope it helps.

2018-07-08 22:24
by RajN


-3

in JQuery $.ajax you will receive an array, traverse through the elements and get the sum.

2012-04-03 20:50
by Har
Thanks a lot for the response, but I'm trying to figure out how to do this with Json.NET in C# - Brent Barbata 2012-04-03 20:53