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?
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.
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.
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.
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With