Как стать автором
Обновить

Комментарии 31

Что-то я ни одного метода LINQ не увидел. Правильнее было бы назвать API Вконтакте и XDocument.
Сначала так и задумывалось, потом почему-то переименовал. Спасибо, вернул.
foreach со вложенным if вместо Where/Select — это тошнотворно, конечно.
Может быть. Но я писал так, как смог бы понять, если бы занимался этим впервые, не зная LINQ.
Не зная LINQ — через XPath (хотя я бы и сейчас писал через XPath).

А зачем иначе-то писать?
А это уже читатель сможет сделать потом. Я же не прошу все время использовать такие примитивные конструкции, как в этом примере. Это для того, чтобы «пощупать» .xml и явно вытащить из него все, что нужно.
А зачем это может быть нужно и кому?

Чтобы «пощупать» xml, достаточно на него один раз посмотреть.
Наверное тем людям, которые не знают LINQ, но хотят любым понятным способом начать работать с API ВКонтакте. Я просто пытался уменьшить порог вхождения.
Людям, которые не умеют работать ни с LINQ, ни с XPath, надо сначала научиться работать с этими технологиями, а только потом взаимодействовать с API сторонних сервисов.

(на всякий случай напомню, что речь идет в контексте C#)
Полностью согласен, но незнание этих технологий не мешает понимать такие простые вещи. А потом, если надо будет, можно использовать специальные для этого инструменты.
А что тут понимать?
получить все сообщения с пользователем, обработать узлы xml

Это тоже самое, что изучать Лого. Вроде все понятно, но для первого знакомства (конечно, я говорю про детей) подойдет.
получить все сообщения с пользователем, обработать узлы xml

Это надо делать средствами, заложенными в язык/платформу. А не так, как это делаете вы.
foreach заложен в платформу. И дело даже не в этом.
Дело как раз в этом.

Ваш код — это пример, как писать не надо.
Когда вы объясняете ребенку как складывать числа, вы показываете ему на пальцах или яблоках. Но это же не означает, что вы подразумеваете, что он будет так вычислять всю свою жизнь.
Программисты — не дети, у них нормально с абстрактным мышлением и памятью.
Мне интересная тема поста, спасибо большое. Но, кроме понимания, мне было бы интересно увидеть как это писать правильно. Могли бы вы написать вариант с использованием LINQ to XML, так сказать, для сравнения?
Вам спасибо. Ниже уже есть комментарий с использованием LINQ. Укажу его в статье.
Я почему-то текст на вашей картинке прочитал как XML+C≠♥
Спасибо за статью!

> Пожалуйста, указывайте на любые недочеты в статье. Буду учиться.

Я позволил себе последний код чуть чуть оптимизировать:

while(true)
{
    var doc = XDocument.Load("https://api.vk.com/method/messages.getHistory.xml?uid=12345&offset=" + m + "&count="+n+"&access_token=" + token);// Загружаем наш xml с сервера и начнем обработку

    foreach (var el in doc.Root.Elements("message"))// Раскрываем корневой узел
    {
        foreach (var el_msg in el.Elements("attachment"))// Теперь в узле message
        {
            foreach (var el_attch in el_msg.Elements("photo"))
            {
                foreach (var el_photo in el_attch.Elements("src_xbig"))
                {
                    // Скачиваем фотографию в img/
                    src_client.DownloadFile(el_photo.Value, "img/img" + k + ".jpg");
                    k++;
                }
            }
        }
    }
    // Ну и конечно увеличение параметра count
    m += n;
}


А для не совсем маленьких, так же сделал linq вариант:

while (true)
{
    var doc = XDocument.Load("https://api.vk.com/method/messages.getHistory.xml?uid=12345&offset=" + m + "&count=" + n + "&access_token=" + token);// Загружаем наш xml с сервера и начнем обработку
    var photoElements=
    doc.Root.Elements("message")
        .SelectMany(el => el.Elements("attachment")
        .SelectMany(el_msg => el_msg.Elements("photo")
        .SelectMany(elAttch => elAttch.Elements("src_xbig"))));

    foreach (var el_photo in photoElements)
    {
        // Скачиваем фотографию в img/
        src_client.DownloadFile(el_photo.Value, "img/img" + k + ".jpg");
        k++;
    }
    // Ну и конечно увеличение параметра count
    m += n;
}


Можно так же еще сделать десериализацию данных без ручного разбора — но в рамках этой задачи наверное смысла нет.
Мне нравится ваш код. Спасибо за отзыв.
Мне кажется, или тут достаточно одного XPath-запроса? Дайте посмотреть на приходящий XML.
Вам не кажется.
Спасибо. Специально для любителей XPath, написал вариант с ним.
Я б писал как-то так:

using System;
using System.Linq;
using System.Net;
using System.Xml.Linq;
using System.Xml.XPath;

namespace Test
{
    class Program
    {
        private readonly WebClient _webClient = new WebClient();

        public string Token
        {
            get { return "token"; }
        }
        public string UserID
        {
            get { return "uid"; }
        }
        public string XQueryString
        {
            get { return "//message//attachment//photo//src_big"; }
        }

        static void Main()
        {
            new Program().Run();
        }

        private void Run()
        {
            const int offset = 0, count = 10;

            var url = MakeUrl(UserID, offset, count, Token);
            var doc = XDocument.Load(url);
            var els = doc.XPathSelectElements(XQueryString);

            foreach (var t in els.Select((val, index) => new { val.Value, Index = index }))
            {
                _webClient.DownloadFileAsync(new Uri(t.Value), string.Format("img/img{0}.jpg", t.Index));
            }
        }

        private string MakeUrl(string uid, int offset, int count, string token)
        {
            const string queryFormatString =
                "https://api.vk.com/method/messages.getHistory.xml?uid={0}&offset={1}&count={2}&access_token={3}";

            return string.Format(queryFormatString, uid, offset, count, token);
        }
    }
}
А смысл xml использовать, если некоторые методы типа execute все равно возращают json, который, к слову, более удобен для работы.
Часто ли приходится обрабатывать капчу вконтакте?
При подобных запросах — редко. В основном, при общении.
Сериализация уже на усмотрение пользователя. Я лишь хотел показать, как можно использовать XDocument для этого.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории