Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Searching for a specific JToken by name in a JObject hierarchy

Tags:

json

c#

json.net

I have some Json response from server, for example:

{"routes" : [   {      "bounds" : {         "northeast" : {            "lat" : 50.4639653,            "lng" : 30.6325177         },         "southwest" : {            "lat" : 50.4599625,            "lng" : 30.6272425         }      },      "copyrights" : "Map data ©2013 Google",      "legs" : [         {            "distance" : {               "text" : "1.7 km",               "value" : 1729            },            "duration" : {               "text" : "4 mins",               "value" : 223            }, 

And I want to get the value of token 'text' from

      "legs" : [         {            "distance" : {               "text" : "1.7 km",               "value" : 1729            }, 

which is string with value "1.7 km".

Question: is there any build-in function in NewtonsoftJson lib which can be look like:

public string(or JToken) GetJtokenByName(JObject document, string jtokenName) 

or do I need to implement some recursive method which will search JToken by name in all JTokens and JArrays in JObject?

like image 870
Dima Serdechnyi Avatar asked Oct 28 '13 21:10

Dima Serdechnyi


People also ask

What is the difference between JObject and JToken?

So you see, a JObject is a JContainer , which is a JToken . Here's the basic rule of thumb: If you know you have an object (denoted by curly braces { and } in JSON), use JObject. If you know you have an array or list (denoted by square brackets [ and ] ), use JArray.

How do you access JObject values?

The simplest way to get a value from LINQ to JSON is to use the Item[Object] index on JObject/JArray and then cast the returned JValue to the type you want. JObject/JArray can also be queried using LINQ.

What is JToken in C#?

JToken is the abstract base class of JObject , JArray , JProperty , and JValue , which represent pieces of JSON data after they have been parsed. JsonToken is an enum that is used by JsonReader and JsonWriter to indicate which type of token is being read or written.

What does JToken parse do?

Parse() to parse a JSON string you know to represent an "atomic" value, requiring the use of JToken. Parse() in such a case. Similarly, JToken. FromObject() may be used to serialize any sort of c# object to a JToken hierarchy without needing to know in advance the resulting JSON type.


1 Answers

If you are looking for a very specific token and know the path to it, you can navigate to it easily using the built-in SelectToken() method. For example:

string distance = jObject.SelectToken("routes[0].legs[0].distance.text").ToString(); 

If you need to find all occurences of a token with a given name in your JSON, no matter where they occur, then yes you'd need a recursive method. Here is one that might do the trick:

public static class JsonExtensions {     public static List<JToken> FindTokens(this JToken containerToken, string name)     {         List<JToken> matches = new List<JToken>();         FindTokens(containerToken, name, matches);         return matches;     }      private static void FindTokens(JToken containerToken, string name, List<JToken> matches)     {         if (containerToken.Type == JTokenType.Object)         {             foreach (JProperty child in containerToken.Children<JProperty>())             {                 if (child.Name == name)                 {                     matches.Add(child.Value);                 }                 FindTokens(child.Value, name, matches);             }         }         else if (containerToken.Type == JTokenType.Array)         {             foreach (JToken child in containerToken.Children())             {                 FindTokens(child, name, matches);             }         }     } } 

Here is a demo:

class Program {     static void Main(string[] args)     {         string json = @"         {             ""routes"": [                 {                     ""bounds"": {                         ""northeast"": {                             ""lat"": 50.4639653,                             ""lng"": 30.6325177                         },                         ""southwest"": {                             ""lat"": 50.4599625,                             ""lng"": 30.6272425                         }                     },                     ""legs"": [                         {                             ""distance"": {                                 ""text"": ""1.7 km"",                                 ""value"": 1729                             },                             ""duration"": {                                 ""text"": ""4 mins"",                                 ""value"": 223                             }                         },                         {                             ""distance"": {                                 ""text"": ""2.3 km"",                                 ""value"": 2301                             },                             ""duration"": {                                 ""text"": ""5 mins"",                                 ""value"": 305                             }                         }                     ]                 }             ]         }";          JObject jo = JObject.Parse(json);          foreach (JToken token in jo.FindTokens("text"))         {             Console.WriteLine(token.Path + ": " + token.ToString());         }     } } 

Here is the output:

routes[0].legs[0].distance.text: 1.7 km routes[0].legs[0].duration.text: 4 mins routes[0].legs[1].distance.text: 2.3 km routes[0].legs[1].duration.text: 5 mins 
like image 54
Brian Rogers Avatar answered Sep 24 '22 03:09

Brian Rogers