JSON Парсинг проверяет, существует ли значение в массиве - PullRequest
1 голос
/ 11 июля 2020

Я новичок и только изучаю синтаксический анализ с помощью JSON

Я проверяю, существует ли значение в массиве. мой код работает, но я просто хочу спросить самый короткий код или улучшение для этого?

вот что я получаю: m3u8 Он случайно существует от массива [0] до [4] . поэтому я попробовал метод .contains.

  public static async Task<string> GetInfoAsync(string url)
    {
        var resource = await GetWebSourceAsync(url);
        JObject jObject = JObject.Parse(resource);

        var m3u8 = string.Empty;

        if (jObject["data"]["program"]["video"][0].Value<string>().Contains("#EXTM3U"))
        {
            m3u8 = jObject["data"]["program"]["video"][0]["m3u8"].Value<string>();
        }
        else if (jObject["data"]["program"]["video"][1].Value<string>().Contains("#EXTM3U"))
        {
            m3u8 = jObject["data"]["program"]["video"][1]["m3u8"].Value<string>();
        }
        else if (jObject["data"]["program"]["video"][2].Value<string>().Contains("#EXTM3U"))
        {
            m3u8 = jObject["data"]["program"]["video"][2]["m3u8"].Value<string>();
        }
        else if (jObject["data"]["program"]["video"][3].Value<string>().Contains("#EXTM3U"))
        {
            m3u8 = jObject["data"]["program"]["video"][3]["m3u8"].Value<string>();
        }
        else if (jObject["data"]["program"]["video"][4].Value<string>().Contains("#EXTM3U"))
        {
            m3u8 = jObject["data"]["program"]["video"][4]["m3u8"].Value<string>();
        }

        return m3u8;
    }

Вот структуры JSON

Ответы [ 3 ]

2 голосов
/ 11 июля 2020

Вы можете использовать LINQ в своих интересах:

JObject jObject = new JObject();
var m3u = jObject["data"]["program"]["video"]
    .Where(i => i.Value<string>().Contains("#EXTM3U"))
    .FirstOrDefault()
    ?["m3u8"].Value<string>();

Сообщите мне, если это не поможет.

2 голосов
/ 11 июля 2020

Предполагая, что ваш json текст похож на (он может содержать гораздо больше данных, это не имеет значения):

{
    "data": {
        "program": {
            "video": [
                {
                    "m3u8Url": "http://go.to/video1",
                    "vid": "",
                    "rp": 0 
                },
                {
                    "m3u8Url": "http://go.to/video2",
                    "m3u8": "#EXTM3U #EXT-X-TARGET...",
                    "vid": "",
                    "rp": 0
                },
                {
                    "m3u8Url": "http://go.to/video3",
                    "vid": "",
                    "rp": 0
                }
            ]
        }
    }
}

Вы можете получить первое видео, содержащее # EXTM3U используя следующий код:

var anonymousObj = new
{
    data = new
    {
        program = new
        {
            video = new[]
            {
                new
                {
                    m3u8Url = "",
                    m3u8 = "",
                    vid = "",
                    rp = 0
                }
            }
        }
    }
};
var obj = JsonConvert.DeserializeAnonymousType(json, anonymousObj);
var video = obj?.data?.program?.video?.FirstOrDefault(v => v.m3u8?.Contains("#EXTM3U") == true);

Другое решение , если вы используете Visual Studio, вы можете сопоставить любой текст JSON с классом с помощью редактора. Go для редактирования -> Специальная вставка -> Вставить JSON как классы. Вывод, например, JSON будет:

public class Rootobject
{
    public Data data { get; set; }
}

public class Data
{
    public Program program { get; set; }
}

public class Program
{
    public Video[] video { get; set; }
}

public class Video
{
    public string m3u8Url { get; set; }
    public string vid { get; set; }
    public int rp { get; set; }
    public string m3u8 { get; set; }
    //it will have other props
}

Затем вы можете использовать JsonConvert и десериализовать его до типа Rootobject.

var obj2 = JsonConvert.DeserializeObject<Rootobject>(json);
var video2 = obj2?.data?.program?.video?.FirstOrDefault(v => v.m3u8?.Contains("#EXTM3U") == true);
0 голосов
/ 11 июля 2020

Хорошо, это решение от @Volodymyr Большое вам спасибо.

  public static async Task<string> GetInfoAsync(string url, EpisodeInfo info)
    {
        var resource = await GetWebSourceAsync(url);

        JObject jObject = JObject.Parse(resource);
        return jObject["data"]["program"]["video"]
            .Where(i => i.ToString().Contains("#EXTM3U"))
            .FirstOrDefault()
            ?["m3u8"].ToString();
    }

и вот решение от @dbvega Спасибо тоже.

   public static async Task<string> GetWebSourceAsync(string url)
    {
        var handler = new HttpClientHandler
        {
            Proxy = null,
            UseProxy = false
        };

        using (var client = new HttpClient(handler))
        {
            client.DefaultRequestHeaders.Add("Method", "GET");
            client.DefaultRequestHeaders.UserAgent.ParseAdd("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36");

            using (HttpResponseMessage response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead))
            {
                response.EnsureSuccessStatusCode();
                string json = await response.Content.ReadAsStringAsync();
                var obj = JsonConvert.DeserializeObject<Rootobject>(json);
                var result = obj?.data?.program?.video?.FirstOrDefault(v => v.m3u8?.Contains("#EXTM3U") == true);
                return JsonConvert.SerializeObject(result, Newtonsoft.Json.Formatting.Indented);
            }
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...