【问题标题】:How do I parse a specific section from a JSON text to make a list of heroes from League of Legends如何从 JSON 文本中解析特定部分以制作英雄联盟中的英雄列表
【发布时间】:2019-06-10 00:24:44
【问题描述】:

我正在尝试从 JSON url:http://ddragon.leagueoflegends.com/cdn/6.24.1/data/en_US/champion.json 获取英雄联盟中所有英雄的名字,并且我正在尝试在“name”之后获取该英雄的名字:来自 JSON url .

如何获得所有英雄的名字?

我尝试过使用索引和子字符串,但我觉得它是硬编码

$public static async void GetHtml()
        {
            var url = "http://ddragon.leagueoflegends.com/cdn/6.24.1/data/en_US/champion.json ";
            var httpClient = new HttpClient();
            var html = await httpClient.GetStringAsync(url);`

            var htmlDocument = new HtmlDocument(); 

            htmlDocument.LoadHtml(html);

            var jsonData =  JObject.Parse(html);

            var index = jsonData.ToString().IndexOf("name", StringComparison.Ordinal);

            var champName= jsonData.ToString().Substring(index, 20);
                Console.WriteLine(champName);
        }

我只得到一个名字,我的目标是在一个列表中得到所有英雄的名字。顺便说一句,我正在使用 JSON.Net

【问题讨论】:

    标签: c# json parsing console-application


    【解决方案1】:

    首先,您尝试解析的 html 变量只是一个 JSON 字符串。你根本不需要那个HtmlDocument

    一般来说,您需要创建一组类来反序列化数据。由于您只需要部分信息,因此您只需要最少的一组类来描述结构。

    在 JSON.net 中,最佳匹配结构是 Dictionary<,>。结果将有 Keys 是成员名称,值是我们选择的任何记录类型。在这种情况下,我们只关心成员名称,因此我们可以使用空记录类型。

    在这种情况下,我们感兴趣的部分的最小 JSON 表示形式如下所示:

    {
        {
            "Aatrox": { "name":"Aatrox" },
            "Ahri": { "name":"Ahri" },
            "AurelionSol": { "name":"Aurelion Sol" }
        }
    }
    

    这是一个将原始文件解析成的最小类结构,它只会捕获我们关心的信息:

    class ChampionsRoot
    {
        public Dictionary<string, ChampionInfo> data;
    }
    
    class ChampionInfo
    {
        public string name;
    }
    

    现在我们只需要一些代码来从数据中提取这些名称:

    static void Main()
    {
        var url = "http://ddragon.leagueoflegends.com/cdn/6.24.1/data/en_US/champion.json";
        var httpClient = new HttpClient();
        var source = httpClient.GetStringAsync(url).Result;
    
        var root = JsonConvert.DeserializeObject<ChampionsRoot>(source);
        var names = root.data.Select(kv => kv.Value.name).ToArray();
    }
    

    现在names 是一个包含所有name 值的数组。


    或者如果你想使用正则表达式:

    void Main()
    {
        var url = "http://ddragon.leagueoflegends.com/cdn/6.24.1/data/en_US/champion.json";
        var httpClient = new HttpClient();
        var source = httpClient.GetStringAsync(url).Result;
    
        // "name":"(value)"
        var regex = new Regex("\"name\":\"([^\"]+)\"");
        var matches = regex.Matches(source);
        var names = matches.OfType<Match>().Select(_ => _.Groups[1].Value).ToArray();
    }
    

    数据中没有其他 name 字段,因此返回的结果与 JSON.net 版本相同,只是没有依赖关系。

    【讨论】:

    • 还有一个问题,如果我想获得例如“Aatrox.png”,如何从图像转到完整?再次感谢:)
    • @MazzEbra 您需要另一个类来捕获image 成员。像struct ChampionImage { public string full; } 这样的东西,并将public ChampionImage image; 添加到ChampionInfo 类中。
    • 再次感谢伙计。你真棒
    • @MazzEbra 我已经将一个快速的 LINQPad 脚本与最小版和完整版的类一起提供给您一个想法。 Check it out here.
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-21
    • 1970-01-01
    • 2021-07-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多