一尘不染

在JObject层次结构中按名称搜索特定的JToken

c#

我有一些来自服务器的Json响应,例如:

{"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”的字符串。

问题: NewtonsoftJson lib中是否有任何内置函数,看起来像:

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

还是我需要实现某种递归方法,该方法将按名称搜索JObject中所有JToken和JArray中的JToken?


阅读 759

收藏
2020-05-19

共1个答案

一尘不染

如果您正在寻找一个非常特定的令牌并知道其路径,则可以使用内置SelectToken()方法轻松导航到该令牌。例如:

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

如果您需要在JSON中查找具有给定名称的令牌的所有出现,无论它们出现在什么地方,那么是的,您将需要一个递归方法。这可能会达到目的:

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
2020-05-19