首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何解析带有Yahoo索引的json数组

如何解析带有Yahoo索引的json数组
EN

Stack Overflow用户
提问于 2019-06-21 15:35:14
回答 1查看 116关注 0票数 1

考虑到来自Yahoo的这一响应,我试图使用Newtonsoft.Json和ASP.NET / C#来解析玩家。我还想在最后检查count的值。

代码语言:javascript
复制
{
  "fantasy_content": {
    "xml:lang": "en-US",
    "yahoo:uri": "/fantasy/v2/game/nfl/players",
    "game": [
      {
        "game_key": "390",
        "game_id": "390",
        "name": "Football",
        "code": "nfl",
        "type": "full",
        "url": "https://football.fantasysports.yahoo.com/f1",
        "season": "2019",
        "is_registration_over": 0,
        "is_game_over": 0,
        "is_offseason": 0
      },
      {
        "players": {
          "0": {
            "player": [
              [
                {
                  "player_key": "390.p.30972"
                },
                {
                  "player_id": "30972"
                },
                {
                  "name": {
                    "full": "Saquon Barkley",
                    "first": "Saquon",
                    "last": "Barkley",
                    "ascii_first": "Saquon",
                    "ascii_last": "Barkley"
                  }
                },
                {
                  "editorial_player_key": "nfl.p.30972"
                },
                {
                  "editorial_team_key": "nfl.t.19"
                },
                {
                  "editorial_team_full_name": "New York Giants"
                },
                {
                  "editorial_team_abbr": "NYG"
                },
                {
                  "bye_weeks": {
                    "week": "11"
                  }
                },
                {
                  "uniform_number": "26"
                },
                {
                  "display_position": "RB"
                },
                {
                  "headshot": {
                    "url": "https://s.yimg.com/iu/api/res/1.2/RtPm7fdFHthz1._DrpkAqA--~C/YXBwaWQ9eXNwb3J0cztjaD0yMzM2O2NyPTE7Y3c9MTc5MDtkeD04NTc7ZHk9MDtmaT11bGNyb3A7aD02MDtxPTEwMDt3PTQ2/https://s.yimg.com/xe/i/us/sp/v/nfl_cutout/players_l/09242018/30972.png",
                    "size": "small"
                  },
                  "image_url": "https://s.yimg.com/iu/api/res/1.2/RtPm7fdFHthz1._DrpkAqA--~C/YXBwaWQ9eXNwb3J0cztjaD0yMzM2O2NyPTE7Y3c9MTc5MDtkeD04NTc7ZHk9MDtmaT11bGNyb3A7aD02MDtxPTEwMDt3PTQ2/https://s.yimg.com/xe/i/us/sp/v/nfl_cutout/players_l/09242018/30972.png"
                },
                {
                  "is_undroppable": "0"
                },
                {
                  "position_type": "O"
                },
                [],
                {
                  "eligible_positions": [
                    {
                      "position": "RB"
                    }
                  ]
                },
                [],
                [],
                []
              ]
            ]
          },
          "1": {
            "player": [
              [
                {
                  "player_key": "390.p.29238"
                },
                {
                  "player_id": "29238"
                },
                {
                  "name": {
                    "full": "Ezekiel Elliott",
                    "first": "Ezekiel",
                    "last": "Elliott",
                    "ascii_first": "Ezekiel",
                    "ascii_last": "Elliott"
                  }
                },
                {
                  "editorial_player_key": "nfl.p.29238"
                },
                {
                  "editorial_team_key": "nfl.t.6"
                },
                {
                  "editorial_team_full_name": "Dallas Cowboys"
                },
                {
                  "editorial_team_abbr": "Dal"
                },
                {
                  "bye_weeks": {
                    "week": "8"
                  }
                },
                {
                  "uniform_number": "21"
                },
                {
                  "display_position": "RB"
                },
                {
                  "headshot": {
                    "url": "https://s.yimg.com/iu/api/res/1.2/.0ocryeNkGmnFWlYOhT4hw--~C/YXBwaWQ9eXNwb3J0cztjaD0yMzM2O2NyPTE7Y3c9MTc5MDtkeD04NTc7ZHk9MDtmaT11bGNyb3A7aD02MDtxPTEwMDt3PTQ2/https://s.yimg.com/xe/i/us/sp/v/nfl_cutout/players_l/09272018/29238.png",
                    "size": "small"
                  },
                  "image_url": "https://s.yimg.com/iu/api/res/1.2/.0ocryeNkGmnFWlYOhT4hw--~C/YXBwaWQ9eXNwb3J0cztjaD0yMzM2O2NyPTE7Y3c9MTc5MDtkeD04NTc7ZHk9MDtmaT11bGNyb3A7aD02MDtxPTEwMDt3PTQ2/https://s.yimg.com/xe/i/us/sp/v/nfl_cutout/players_l/09272018/29238.png"
                },
                {
                  "is_undroppable": "0"
                },
                {
                  "position_type": "O"
                },
                [],
                {
                  "eligible_positions": [
                    {
                      "position": "RB"
                    }
                  ]
                },
                [],
                [],
                []
              ]
            ]
          },
          "2": {
            "player": [
              [
                {
                  "player_key": "390.p.30180"
                },
                {
                  "player_id": "30180"
                },
                {
                  "name": {
                    "full": "Alvin Kamara",
                    "first": "Alvin",
                    "last": "Kamara",
                    "ascii_first": "Alvin",
                    "ascii_last": "Kamara"
                  }
                },
                {
                  "editorial_player_key": "nfl.p.30180"
                },
                {
                  "editorial_team_key": "nfl.t.18"
                },
                {
                  "editorial_team_full_name": "New Orleans Saints"
                },
                {
                  "editorial_team_abbr": "NO"
                },
                {
                  "bye_weeks": {
                    "week": "9"
                  }
                },
                {
                  "uniform_number": "41"
                },
                {
                  "display_position": "RB"
                },
                {
                  "headshot": {
                    "url": "https://s.yimg.com/iu/api/res/1.2/loANJKjPdmUu1gM1jyKK1A--~C/YXBwaWQ9eXNwb3J0cztjaD0yMzM2O2NyPTE7Y3c9MTc5MDtkeD04NTc7ZHk9MDtmaT11bGNyb3A7aD02MDtxPTEwMDt3PTQ2/https://s.yimg.com/xe/i/us/sp/v/nfl_cutout/players_l/08252018/30180.png",
                    "size": "small"
                  },
                  "image_url": "https://s.yimg.com/iu/api/res/1.2/loANJKjPdmUu1gM1jyKK1A--~C/YXBwaWQ9eXNwb3J0cztjaD0yMzM2O2NyPTE7Y3c9MTc5MDtkeD04NTc7ZHk9MDtmaT11bGNyb3A7aD02MDtxPTEwMDt3PTQ2/https://s.yimg.com/xe/i/us/sp/v/nfl_cutout/players_l/08252018/30180.png"
                },
                {
                  "is_undroppable": "0"
                },
                {
                  "position_type": "O"
                },
                [],
                {
                  "eligible_positions": [
                    {
                      "position": "RB"
                    }
                  ]
                },
                [],
                [],
                []
              ]
            ]
          },
          "count": 3
        }
      }
    ],
    "time": "181.84494972229ms",
    "copyright": "Data provided by Yahoo! and STATS, LLC",
    "refresh_rate": "60"
  }
}

有两件事让我失望。

  1. game是一个看起来很奇怪的数组,而且
  2. 每个球员在他们面前都有一个索引,比如0: { player: { //dah dah dah }

如果没有索引,我可能会使用如下的方法来找出它:

代码语言:javascript
复制
var jObject = JObject.Parse(await response.Content.ReadAsStringAsync());
if (jObject.ContainsKey("players"))
{
    var yPs = jObject["players"].ToObject<YahooPlayerListJson>();
    yPlayerList.AddRange(yPs.YPlayers);
    if(yPs.Count < 25) { f = 5000; }
}

但指数给我带来了困难。如何解析这个JSON?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-06-22 22:28:28

这是一种非常糟糕的JSON格式。异构数组使得使用起来特别困难。在我看来,这些数据是从XML转换而来的(很糟糕)。如果是这样的话,直接使用XML可能更简单。无论如何,我们都能让它发挥作用。这是我会采取的方法。

  1. 创建一些类来捕获您感兴趣的播放器数据: 公共类播放器{公共字符串PlayerKey { get;set;}公共字符串PlayerId { get;set;}公共字符串EditorialPlayerKey { get;set;}公共字符串EditorialTeamKey { get;set;}公共字符串EditorialTeamKey{ get;EditorialTeamFullName { get;set;}公共字符串EditorialTeamAbbr { get;}公共周ByeWeeks { get;set;}公共字符串UniformNumber { get;}公共字符串DisplayPosition { get;set;}公共字符串EditorialTeamFullName{ get;公共字符串ImageUrl { get;set;}公共字符串IsUndroppable { get;set;}公共字符串PositionType { get;}公共字符串PositionType{ get;set;}公共字符串类名{ public string Full { get;set;} public string首先{ get;set;}公共字符串最后一个{ get;set;}公共字符串图片{公共字符串Url { get;set;}公共字符串大小{ get;set;}}公共类周{JsonProperty(“周”)公共int数{ get;set;}公共类位置{JsonProperty(“位置”)公共字符串名{ get;set;}}
  2. 设置使用SnakeCaseNamingStrategy配置的序列化程序。这将处理将JSON中的snake_case属性名称转换为C#类中的ProperCase属性名称的过程。 JsonSerializer序列化程序=新的JsonSerializer { ContractResolver =新的DefaultContractResolver { NamingStrategy =新的SnakeCaseNamingStrategy() };
  3. 将JSON解析为JObject。 字符串json =等待response.Content.ReadAsStringAsync();JObject root = JObject.Parse(json);
  4. 然后使用LINQ到JSON查询填充Players列表,如下所示。 在这里,我使用带有递归下降SelectTokens()表达式的JsonPath作为深入到player对象的快捷方式。JSON中的每个播放器实际上都是一个包含混合内容数组的数组,其中的内容包括一些对象,每个对象包含一个不同的属性,以及一些无用的空数组。因此,我将内部数组过滤为仅包含真实数据的对象,然后使用SelectMany()将其所有属性收集到一个平面Enumerable<JProperty>中,并将其放置到临时JObject中。在这里,我将ToObject()与前面配置的序列化程序一起使用,以便从JObject创建一个新的Player实例,并返回Player,以便将其放入结果列表中。 列表参与者= root.SelectTokens("$..player") .Select(jt => { JObject tempObj =新JObject( jt.Children() .First() .Children() .SelectMany(jo => jo.Properties) );返回tempObj.ToObject(序列化器);) .ToList();
  5. 如果您想从JSON中获取count并将其与实际检索的球员数量进行比较,您可以这样做: int playerCount = (int)root.SelectToken("$..players.count");if (players.Count != playerCount)抛出新异常(“列表中的玩家数与玩家数量不匹配!”);

下面是一个工作演示:https://dotnetfiddle.net/8KYNNn

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56706506

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档