解析复杂JSON字符串的最佳实践

3
我正在学习C#,决定尝试解析一些JSON作为项目。我正在使用JSON.NET包,这使得它非常容易。我想知道是否有更好的方法来获取JSON内部更深层次的元素,而不是使用类似[object].[innerObject].[innerinnerObject].[innerinnerinnerObject].name的方式。
这是相关的JSON(从Yahoo YQL获得)。
{
 "query": {
  "count": 1,
  "created": "2013-11-06T04:18:34Z",
  "lang": "en-US",
  "diagnostics": {
   "publiclyCallable": "true",
   "url": {
    "execution-start-time": "0",
    "execution-stop-time": "106",
    "execution-time": "106",
    "content": "http://weather.yahooapis.com/forecastrss?w=2502265"
   },
   "user-time": "108",
   "service-time": "106",
   "build-version": "0.2.1997"
  },
  "results": {
   "channel": {
    "title": "Yahoo! Weather - Sunnyvale, CA",
    "link": "http://us.rd.yahoo.com/dailynews/rss/weather/Sunnyvale__CA/*http://weather.yahoo.com/forecast/USCA1116_f.html",
    "description": "Yahoo! Weather for Sunnyvale, CA",
    "language": "en-us",
    "lastBuildDate": "Tue, 05 Nov 2013 7:55 pm PST",
    "ttl": "60",
    "location": {
     "city": "Sunnyvale",
     "country": "United States",
     "region": "CA"
    },
    "units": {
     "distance": "mi",
     "pressure": "in",
     "speed": "mph",
     "temperature": "F"
    },
    "wind": {
     "chill": "61",
     "direction": "0",
     "speed": "0"
    },
    "atmosphere": {
     "humidity": "52",
     "pressure": "30.19",
     "rising": "1",
     "visibility": "10"
    },
    "astronomy": {
     "sunrise": "6:37 am",
     "sunset": "5:06 pm"
    },
    "image": {
     "title": "Yahoo! Weather",
     "width": "142",
     "height": "18",
     "link": "http://weather.yahoo.com",
     "url": "http://l.yimg.com/a/i/brand/purplelogo//uh/us/news-wea.gif"
    },
    "item": {
     "title": "Conditions for Sunnyvale, CA at 7:55 pm PST",
     "lat": "37.37",
     "long": "-122.04",
     "link": "http://us.rd.yahoo.com/dailynews/rss/weather/Sunnyvale__CA/*http://weather.yahoo.com/forecast/USCA1116_f.html",
     "pubDate": "Tue, 05 Nov 2013 7:55 pm PST",
     "condition": {
      "code": "33",
      "date": "Tue, 05 Nov 2013 7:55 pm PST",
      "temp": "61",
      "text": "Fair"
     },
     "description": "\n<img src=\"http://l.yimg.com/a/i/us/we/52/33.gif\"/><br />\n<b>Current Conditions:</b><br />\nFair, 61 F<BR />\n<BR /><b>Forecast:</b><BR />\nTue - Mostly Clear. High: 72 Low: 48<br />\nWed - Partly Cloudy. High: 75 Low: 51<br />\nThu - AM Clouds/PM Sun. High: 68 Low: 49<br />\nFri - Partly Cloudy. High: 66 Low: 45<br />\nSat - Sunny. High: 64 Low: 46<br />\n<br />\n<a href=\"http://us.rd.yahoo.com/dailynews/rss/weather/Sunnyvale__CA/*http://weather.yahoo.com/forecast/USCA1116_f.html\">Full Forecast at Yahoo! Weather</a><BR/><BR/>\n(provided by <a href=\"http://www.weather.com\" >The Weather Channel</a>)<br/>\n",
     "forecast": [
      {
       "code": "33",
       "date": "5 Nov 2013",
       "day": "Tue",
       "high": "72",
       "low": "48",
       "text": "Mostly Clear"
      },
      {
       "code": "30",
       "date": "6 Nov 2013",
       "day": "Wed",
       "high": "75",
       "low": "51",
       "text": "Partly Cloudy"
      },
      {
       "code": "30",
       "date": "7 Nov 2013",
       "day": "Thu",
       "high": "68",
       "low": "49",
       "text": "AM Clouds/PM Sun"
      },
      {
       "code": "30",
       "date": "8 Nov 2013",
       "day": "Fri",
       "high": "66",
       "low": "45",
       "text": "Partly Cloudy"
      },
      {
       "code": "32",
       "date": "9 Nov 2013",
       "day": "Sat",
       "high": "64",
       "low": "46",
       "text": "Sunny"
      }
     ],
     "guid": {
      "isPermaLink": "false",
      "content": "USCA1116_2013_11_09_7_00_PST"
     }
    }
   }
  }
 }
}

我已经相应地映射了我的类:

public class WeatherInfo
{
    //top level query object
    public jsonquery query { get; set; }
}

public class jsonquery
{
    public jsonresults results { get; set; }
}

public class jsonresults
{
    public jsonchannel channel { get; set; }
}

public class jsonchannel 
{
    public string title { get; set; }
}

目前的设置方式,我得到的标题是"Yahoo! Weather - SunnyVale, CA"

Console.WriteLine(wInfo.query.results.channel.title);

这似乎有些不自然,并且可能变得难以阅读。我是否有更好的方法来调用那些深层次的JSON元素?

问题中未清楚描述您对当前方式的担忧。您是担心遍历对象树所需的执行时间,解析复杂的 JSON 对象的开销,还是其他事情? - M.Babcock
我最担心的是我目前的做法不是良好的编码实践,因为可能会有很多重复的代码,并且可能会在以后造成一些可读性问题。使用 [object].[innerObject].[innerinnerObject].[innerinnerinnerObject].name 看起来太长了。下面的答案看起来是处理它的好方法。 - Alex
1个回答

1
你可以将其拆分成多行,以避免出现重复代码的长行。例如:
var channel = wInfo.query.results.channel;
var title = channel.title;
var link = channel.link;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接