在不知道c#中的密钥的情况下读取json

时间:2016-09-20 02:47:08

标签: c# json

我想解析下面提到的JSON并获取 screenshot.thumbnailUrl 的所有值。但下面是我的约束:

并非所有节点都有截屏。在这个例子中只有"天气"和"实体"拥有它。

我不知道节点名称。在这个例子中,我不知道会有一个名为" weather"或"实体"。这些节点是根据我获取json的查询自动生成的。

有两个可能存在屏幕截图的地方。 (1)在rootobject的孩子中,例如weather.screenshot(2)在rootobject的孩子的所有值中,例如entities.value [0] .screenshot,entities.value [1] .screenshot等。

{   "_type": "SearchResponse",   "queryContext": {},   "webPages": {}, "entities": {
    "queryScenario": "DominantEntity",
    "value": [
      {
        "_type": "Place",
        "id": "https://www.someapi.com/api/v6/#Entities.0",
        "screenshot": {
          "thumbnailUrl": "http://Screenshot_URL_I_Want",
          "width": 285
        },
        "name": "Seattle",
        "entityPresentationInfo": {},
        "bingId": "5fbba6b8-85e1-4d41-9444-d9055436e473",
        "boundingBox": [],
        "weather": {},
        "timeZone": "Pacific Standard Time"
      }
    ]   },   "images": {},   "weather": {
    "id": "https://www.someapi.com/api/v6/#Weather",
    "screenshot": {
      "thumbnailUrl": "http://Screenshot_URL_I_Want",
       "width": 285
    },
    "location": {},
    "currentWeather": {},
    "dailyForecast": []   },   "rankingResponse": {} }

2 个答案:

答案 0 :(得分:3)

这对我有用......我正在寻找更清洁的解决方案......

static async void getJobject(string jsonstring)
        {
            JObject response = await JObject.Parse(jsonstring);
            foreach (var node in response.Children())
            {
                Console.WriteLine(node.Path);
                string propertyPath = node.Path + ".screenshot.thumbnailUrl";
                var token = response.SelectToken(propertyPath);

                if (token != null)
                {
                    Console.WriteLine("Check this=> " + token.ToString()); //Prints screenshot URL from weather
                }
                else
                {
                    propertyPath = node.Path + ".value";
                    token = response.SelectToken(propertyPath);
                    if (token != null)
                    {
                        int count = token.Children().Count();
                        for (int i = 0; i < count; i++)
                        {
                            propertyPath = node.Path + ".value" + "[" + i.ToString() + "]" + ".screenshot.thumbnailUrl";
                            var mytoken = response.SelectToken(propertyPath);
                            if (mytoken != null)
                            {
                                Console.WriteLine("Check this=> " + mytoken.ToString()); //Prints screenshot URL from entities
                            }
                        }


                    }
                }

            }
        }

答案 1 :(得分:2)

您可以使用这样的代码来解析JSon并递归迭代它。您可能必须优化对RecursiveDescent调用的lambda中的逻辑,以使其对于您的JSON类型正确且健壮:

using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            string json = @"....your JSON ....";

            var node = JToken.Parse(json);

            RecursiveDescent(node, n =>
            {
                JToken url = n["thumbnailUrl"];
                if (url != null && url.Type == JTokenType.String)
                {
                    var nodeWeWant = url?.Parent?.Parent?.Parent?.Parent;

                    Console.WriteLine(nodeWeWant.ToString());
                }
            });
        }

        static void RecursiveDescent(JToken node, Action<JObject> action)
        {
            if (node.Type == JTokenType.Object)
            {
                action((JObject)node);
                foreach (JProperty child in node.Children<JProperty>())
                    RecursiveDescent(child.Value, action);
            }
            else if (node.Type == JTokenType.Array)
            {
                foreach (JToken child in node.Children())
                    RecursiveDescent(child, action);
            }
        }
    }
}