从c#中的多个json数组解析数据

时间:2016-11-24 02:05:20

标签: c# json json.net

我正在尝试搜索此Json代码以查找统计信息:

{
    "summonerId": 32033681,
    "modifyDate": 1403658807000,
    "champions": [{
        "id": 40,
        "stats": {
            "totalSessionsPlayed": 1,
            "totalSessionsLost": 0,
            "totalSessionsWon": 1,
            "totalChampionKills": 1,
            "totalDamageDealt": 27006,
            "totalDamageTaken": 9924,
            "mostChampionKillsPerSession": 1,
            "totalMinionKills": 17,
            "totalDoubleKills": 0,
            "totalTripleKills": 0,
            "totalQuadraKills": 0,
            "totalPentaKills": 0,
            "totalUnrealKills": 0,
            "totalDeathsPerSession": 2,
            "totalGoldEarned": 8383,
            "mostSpellsCast": 0,
            "totalTurretsKilled": 2,
            "totalPhysicalDamageDealt": 8957,
            "totalMagicDamageDealt": 18049,
            "totalFirstBlood": 0,
            "totalAssists": 13,
            "maxChampionsKilled": 1,
            "maxNumDeaths": 2
        }
    },
    {
        "id": 36,
        "stats": {
            "totalSessionsPlayed": 1,
            "totalSessionsLost": 1,
            "totalSessionsWon": 0,
            "totalChampionKills": 0,
            "totalDamageDealt": 14267,
            "totalDamageTaken": 7649,
            "mostChampionKillsPerSession": 0,
            "totalMinionKills": 33,
            "totalDoubleKills": 0,
            "totalTripleKills": 0,
            "totalQuadraKills": 0,
            "totalPentaKills": 0,
            "totalUnrealKills": 0,
            "totalDeathsPerSession": 5,
            "totalGoldEarned": 3258,
            "mostSpellsCast": 0,
            "totalTurretsKilled": 0,
            "totalPhysicalDamageDealt": 4992,
            "totalMagicDamageDealt": 9165,
            "totalFirstBlood": 0,
            "totalAssists": 0,
            "maxChampionsKilled": 0,
            "maxNumDeaths": 5
        }
    }]
}

在下面的示例中,我希望能够为id 36搜索totalSessionsWon。我尝试访问数据如何访问其他JSON文件中的数据,但它不允许我指定冠军的ID我正在寻找:

string jsonInput = new WebClient().DownloadString(@usableurl); //Reads the JSON from the API
string usableJson = @"JObject.Parse(jsonInput)"; //converts the JSON from the API to a usable form
var usableJson["champions"]["stats"]["totalSessionWon"];

有没有办法可以根据之前的ID选择特定的统计数据?

我是新手同时使用JSON和C#,所以特别感谢您的帮助!

2 个答案:

答案 0 :(得分:3)

如果Newtonsoft.Json;对您来说是新的,那么一旦完成安装,您现在可以看看如何install Newtonsoft,我很乐意告诉您,XML,JSON是一种开放标准格式,使用人类可读的文本来传输由属性 - 值对组成的数据对象。从这种字符串中获取数据将像数据库一样容易。

为了轻松地从json字符串中获取数据,我们首先需要创建显示层次结构的json字符串的对象,因此我们需要查看数据或json字符串的外观。因此,如果您看到层次结构的最高级别包含summonerIdmodifyDatechampions内部champions,则可能会有n个冠军详细信息,因此我们创建了冠军名单为champions

现在,在层面的一级,你可以看到冠军身份和他的统计数据,所以统计数据将是另一个关于冠军的阶级。所以你的班级看起来像

public class Rootobject
{
    public int summonerId { get; set; }
    public long modifyDate { get; set; }
    public List<Champion> champions { get; set; }
}

public class Champion
{
    public int id { get; set; }
    public Stats stats { get; set; }
}

public class Stats
{
    public int totalSessionsPlayed { get; set; }
    public int totalSessionsLost { get; set; }
    public int totalSessionsWon { get; set; }
    public int totalChampionKills { get; set; }
    public int totalDamageDealt { get; set; }
    public int totalDamageTaken { get; set; }
    public int mostChampionKillsPerSession { get; set; }
    public int totalMinionKills { get; set; }
    public int totalDoubleKills { get; set; }
    public int totalTripleKills { get; set; }
    public int totalQuadraKills { get; set; }
    public int totalPentaKills { get; set; }
    public int totalUnrealKills { get; set; }
    public int totalDeathsPerSession { get; set; }
    public int totalGoldEarned { get; set; }
    public int mostSpellsCast { get; set; }
    public int totalTurretsKilled { get; set; }
    public int totalPhysicalDamageDealt { get; set; }
    public int totalMagicDamageDealt { get; set; }
    public int totalFirstBlood { get; set; }
    public int totalAssists { get; set; }
    public int maxChampionsKilled { get; set; }
    public int maxNumDeaths { get; set; }
}

既然我们已经得到了结构,我们需要反序列化字符串到我们类型的对象Rootobject。这将转换正常的json字符串以填充对象。现在只需要像吃蛋糕一样获取细节。

using Newtonsoft.Json;

Rootobject rt = JsonConvert.DeserializeObject<Rootobject>(jsonstr);
if(rt.champions[1].id == 36)
{
    Console.WriteLine(rt.champions[1].stats.totalSessionsWon);
}

答案 1 :(得分:2)

由于问题的作者试图使用JObject来查询他们的JSON对象,我想我会用相同的方法给出一个解决方案。

JObject用于使用Linq查询JSON。 Linq是新的C#程序员的半高级主题,但是简而言之,它是一种用于从数据源检索数据的专用查询语言。 Mohit Shrivastrava的回答中概述的方法对于新程序员来说更容易理解。

//converts the JSON from the API to a usable form
JObject usableJson = JObject.Parse(json); 

// retrieve champion objects
JToken champions = usableJson["champions"];

// retrieve the champion desired object using the Linq FirstOrDefault method. 
// This method will return the first object that matches the given query,
// or return null if it does not find a match.
JToken champion = champions.FirstOrDefault(c=> (int)c["id"] == 36);

if (champion != null)
{
    // retrieve the stats object
    JToken stats = champion["stats"];

    // read the totalSessionsWon field from the object.
    int totalSessionsWon = (int) stats["totalSessionsWon"];
}