在 JObject 层次结构中按名称搜索特定 JToken [英] Searching for a specific JToken by name in a JObject hierarchy
问题描述
我有一些来自服务器的 Json 响应,例如:
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
},
我想从
"legs" : [
{
"distance" : {
"text" : "1.7 km",
"value" : 1729
},
这是一个值为1.7 km"的字符串.
which is string with value "1.7 km".
问题:在 NewtonsoftJson 库中是否有任何内置函数,看起来像:
Question: is there any build-in function in NewtonsoftJson lib which can be look like:
public string(or JToken) GetJtokenByName(JObject document, string jtokenName)
或者我是否需要实现一些递归方法,该方法将在 JObject 中的所有 JToken 和 JArray 中按名称搜索 JToken?
or do I need to implement some recursive method which will search JToken by name in all JTokens and JArrays in JObject?
推荐答案
如果您正在寻找一个非常具体的标记并知道它的路径,您可以使用内置的 SelectToken() 轻松导航到它
方法.例如:
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();
如果您需要在 JSON 中查找具有给定名称的令牌的所有出现,无论它们出现在何处,那么是的,您需要一个递归方法.这是一个可以解决问题的方法:
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);
}
}
}
}
这是一个演示:
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());
}
}
}
这是输出:
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
这篇关于在 JObject 层次结构中按名称搜索特定 JToken的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!