[c++] rss

Odpowiedz Nowy wątek
mir
2009-10-16 19:33
mir

Rejestracja: 10 lat temu

Ostatnio: 5 lat temu

0

Witam,

  1. Mam pytanie: czy w C++ można napisać czytnik RSS?
  2. Jakich bibliotek użyć?
  3. Czy w libcurl można to zrobić, jeśli tak to jakich funkcji użyć
  4. Czy dobrze myślę: "pobieram plik xml i go parsuję"?

Pozostało 580 znaków

2009-10-16 20:51

Rejestracja: 15 lat temu

Ostatnio: 4 lata temu

0
  1. Można, sam taki kiedyś napisałem by przetestować klasę do xml.
  2. Systemowych - msxml, lub innej, takiej która Ci najbardziej pasuje.
  3. Można tym tylko ściągnąć xml.
  4. Dobrze, tylko parsowanie zostaw jakiejś gotowej bibliotece do XML, ewentualnie obuduj takową w elementy ułatwiające przeszukiwanie dokumentu - szukanie childa o danej nazwie, pobieranie atrybutów i tekstu.
    Sam XML to tylko kontener do przechowywania informacji, jest jak karta sieciowa. RSS jest jak protokół - ma pewne stałe i ogólnoprzyjęte zasady - dokument musi zawierać gałąź "rss" która musi zawierać gałąź channel, z kolei channel zawiera title, link, description - podstawowe dane o zawartości reszty (tematów), no i zestaw gałęzi "item" które reprezentują "listę postów".

Zacznij od znalezienia/napisania przyjaznej sobie klasy do czytania xml. Jeżeli masz Windows, to na pokładzie jest msxml - czyta, zapisuje i ściąga z netu, synchronicznie i asynchronicznie. Jeżeli xml nie jest gigantyczny i nie masz wstrętu do unicode, to msxml świetnie się do tego nadaje, przynajmniej na start. Trzeba go tylko obudować klasą która będzie konwertowała stringi na VARIANT'y i odwrotnie.

Główny kod mojego synchronicznego czytnika wygląda tak (troszkę html'a wyciąłem, nie pisać o błędach):

RSS::OpenRss(LPWSTR url)
{
    XML doc, rss, channel, title, link, description, item;
    StringStream html;

    if (doc.Open(url))
    {
        if (doc.FindChild(L"rss", TRUE, &rss)
        &&  rss.FindChild(L"channel", TRUE, &channel)
        &&  channel.FindChild(L"title", TRUE, &title)
        &&  channel.FindChild(L"link", TRUE, &link)
        &&  channel.FindChild(L"description", TRUE, &description))
        {
            SetCaption(title.GetText());

            // heading: <a href=link>description</a><br>
            wstring url2;
            wcscpy(url2,url);
            WCHAR *last = wcsrchr(url2, '/');
            if (last) last[1]=0;
            html.WriteA("<html><body><base href='");
            html.WriteW(url2);
            html.WriteA("'><h2><a target='_blank' href='");
            html.WriteW(link.GetText());
            html.WriteA("'>");
            html.WriteW(description.GetText());
            html.WriteA("</a></h2><br>");

            BOOL fReset = TRUE;
            while (channel.FindChild(L"item", fReset, &item))
            {
                fReset = FALSE;
                if (item.FindChild(L"title", TRUE, &title)
                &&  item.FindChild(L"link", TRUE, &link)
                &&  item.FindChild(L"description", TRUE, &description))
                {
                    // heading: <a href=link>title</a><br>description<br>
                    html.WriteA("<hr><h3><a target='_blank' href='");
                    html.WriteW(link.GetText());
                    html.WriteA("'>");
                    html.WriteW(title.GetText());
                    html.WriteA("</a></h3><br>");
                    html.WriteW(description.GetText());
                    html.WriteA("<br>");
                }
            }
            html.WriteA("</body></html>");
            html.Finalize(); // append NULL char
            m_browser.LoadFromString(html.Lock());
            html.Unlock();
        }
    }
}

Pozostało 580 znaków

Odpowiedz

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0