I made a simple RSS reader ~ C edition ~

Certainly, a simple RSS reader that I wrote in C about 2 to 3 years ago. Refer to IBM's developerWorks article and libcurl on Linux. It's like learning XML by displaying article titles and links while analyzing RSS feeds downloaded using / libcurl /) using libxml2. I feel like, but I can't remember how I wrote the XML parsing process orz

Sample code

Downloading RSS feeds with libcurl uses IBM's samples almost as-is, so that Apple's RSS feed summary appears where the download results are displayed.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <curl/curl.h>
#include <sys/types.h>
#include <errno.h>
#include <libxml/xmlerror.h>
#include <libxml/parser.h>
#include <libxml/tree.h>
#include <libxml/xpath.h>

#define MAX_BUF	65536

char wr_buf[MAX_BUF+1];
int  wr_index;

#define PATH "http://www.apple.com/jp/main/rss/hotnews/hotnews.rss"

/*
 * Write data callback function (called within the context of 
 * curl_easy_perform.
 */

size_t write_data( void *buffer, size_t size, size_t nmemb, void *userp ) {
    int segsize = size * nmemb;

    if (wr_index + segsize > MAX_BUF) {
        *(int *)userp = 1;
        return 0;
    }

    memcpy( (void *)&wr_buf[wr_index], buffer, (size_t)segsize );
    wr_index += segsize;
    wr_buf[wr_index] = 0;
    return segsize;
}

/*
 * Parse RSS and print summary.
 */

int
print_rss(char* text) {
    int     i;
    int     size;
    xmlDoc  *doc;
    xmlXPathContextPtr  xpathCtx;
    xmlXPathObjectPtr   xpathObj;
    xmlNodeSetPtr       nodes;
    xmlNode             *node;
    xmlChar             *textcount;

    /* parse an XML in-memory document and build a tree. */
    doc = xmlReadMemory(text, strlen(text), "noname.xml", NULL, 0);
    if (doc == NULL) {
        perror("xmlReadFile");
        return -1;
    }

    /* Create a new xmlXPathContext */
    xpathCtx = xmlXPathNewContext(doc);
    if (xpathCtx == NULL) {
        perror("xmlXPathNewContext");
        xmlFreeDoc(doc);
        xmlCleanupParser();
        return -1;
    }

    /* Get Node list of RSS channel */
    xpathObj = xmlXPathEvalExpression(BAD_CAST "/rss/channel", xpathCtx);
    nodes = xpathObj->nodesetval;
    if (nodes == NULL) {
        xmlXPathFreeContext(xpathCtx);
        xmlFreeDoc(doc);
        xmlCleanupParser();
        return -1;
    }
    
    /* Get and print Title of RSS Feed. */
    size = nodes->nodeNr;
    for (i = 0; i < size; i++) {
        node = xmlFirstElementChild(nodes->nodeTab[i]);
        if (node == NULL) {
            continue;
        }
        for (; node; node = xmlNextElementSibling(node)) {
            if (strcmp((char*)node->name, "title")) {
                    continue;
            }
            textcount = xmlNodeGetContent(node);
            if (textcount) {
                printf("\nTitle: %s\n\n", textcount);
                xmlFree(textcount);
            }
        }
    }
    xmlXPathFreeObject(xpathObj);

    /* Get Node list of RSS items */
    xpathObj = xmlXPathEvalExpression(BAD_CAST "/rss/channel/item", xpathCtx);
    nodes = xpathObj->nodesetval;
    if (nodes == NULL) {
        xmlXPathFreeContext(xpathCtx);
        xmlFreeDoc(doc);
        xmlCleanupParser();
        return -1;
    }

    /* Get and print title and link of each items. */
    size = nodes->nodeNr;
    for (i = 0; i < size; i++) {
        node = xmlFirstElementChild(nodes->nodeTab[i]);
        if (node == NULL) {
            continue;
        }
        for (; node; node = xmlNextElementSibling(node)) {
            if (strcmp((char*)node->name, "title") != 0 &&
                strcmp((char*)node->name, "link") != 0) {
                    continue;
            }
            textcount = xmlNodeGetContent(node);
            if (textcount) {
                printf(" %s:\t%s\n", node->name, textcount);
                xmlFree(textcount);
            }
        }
        printf("\n");
    }

    xmlXPathFreeObject(xpathObj);
    xmlXPathFreeContext(xpathCtx);
    xmlFreeDoc(doc);
    xmlCleanupParser();
    return 0;
}

/*
 * Simple curl application to read the rss feed from a Web site.
 */

int main( void )
{
    CURL *curl;
    CURLcode ret;
    int  wr_error;

    wr_error = 0;
    wr_index = 0;

    curl = curl_easy_init();
    if (!curl) {
        printf("couldn't init curl\n");
        return 0;
    }

    curl_easy_setopt(curl, CURLOPT_URL, PATH);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&wr_error);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);

    ret = curl_easy_perform(curl);
    if ( ret == 0 ) {
        //
        print_rss(wr_buf);
    } else {
        printf( "ret = %d (write_error = %d)\n", ret, wr_error );
        curl_easy_cleanup(curl);
        return 1;
    }

    curl_easy_cleanup(curl);
    return 0;
}

compile

You need libcurl-devel and libxml2-devel to compile, so install them in advance (for CentOS). At compile time, you need to specify the libxml2 header file with the -I option and the library with the -l option.

$ cc -I/usr/include/libxml2 getrss.c -o getrss -lcurl -lxml2

Execution result

A summary of "Apple-Hot News" is displayed.

$ ./getrss

Title: Apple-Hot News

title: Apple launches new iMac Retina 5K display model for 238,800 yen, 15-inch MacBook Pro with pressure-sensitive touch trackpad link: http://www.apple.com/jp/pr/library/2015/05/19Apple-Introduces-15-inch-MacBook-Pro-with-Force-Touch-Trackpad-New-1-999-iMac-with-Retina-5K-Display.html

title: Japan Post Group, IBM, Apple, Japanese senior citizens provide iPad and dedicated application to connect with family and local community through service link: http://www.apple.com/jp/pr/library/2015/04/30Japan-Post-Group-IBM-and-Apple-Deliver-iPads-and-Custom-Apps-to-Connect-Elderly-in-Japan-to-Services-Family-and-Community.html

title: Apple Announces Second Quarter Results link: http://www.apple.com/jp/pr/library/2015/04/27Apple-Reports-Record-Second-Quarter-Results.html

・ ・ ・

Recommended Posts

I made a simple RSS reader ~ C edition ~
A simple RSS reader made with Django
I made a C ++ learning site
I made a simple blackjack with Python
〇✕ I made a game
I made a simple Bitcoin wallet with pycoin
I made a python text
I made a discord bot
I made a quick feed reader using feedparser in Python
I made a simple book application with python + Flask ~ Introduction ~
I made a Line-bot using Python!
I made a CUI-based translation script (2)
I made a wikipedia gacha bot
I made a fortune with Python.
I made a CUI-based translation script
I made a daemon with Python
I made a simple circuit with Python (AND, OR, NOR, etc.)
I made a simple network camera by combining ESP32-CAM and RTSP.
[Python] I made an image viewer with a simple sorting function.
I made a new AWS S3 bucket
I made a dash docset for Holoviews
I made a payroll program in Python!
I touched "Orator" so I made a note
I made a character counter with Python
Beginner: I made a launcher using dictionary
I made a kind of simple image processing tool in Go language.
I made a conversation partner like Siri
I made a script to display emoji
I made a simple timer that can be started from the terminal
I made a Hex map with Python
I made a life game with Numpy
I made a stamp generator with GAN
I made a browser automatic stamping tool.
After studying Python3, I made a Slackbot
I made a configuration file with Python
I made a library for actuarial science
I made a WEB application with Django
I made a neuron simulator with Python
[C language] My locomotive is too slow ~ I made a sl command ~
I made a module in C language to filter images loaded by Python
I made a python dictionary file for Neocomplete
I made a competitive programming glossary with Python
I made a weather forecast bot-like with Python.
I made a spare2 cheaper algorithm for uWSGI
I made a useful tool for Digital Ocean
I made a GUI application with Python + PyQt5
I made a Twitter fujoshi blocker with Python ①
I made a crazy thing called typed tuple
[Python] I made a Youtube Downloader with Tkinter.
I made a router config collection tool Config Collecor
I made a downloader for word distributed expression
I made a LINE Bot with Serverless Framework!
I made a tool to compile Hy natively
I tried adding a Python3 module in C
I made a tool to get new articles
I made a peeping prevention product for telework.
I made a Caesar cryptographic program in Python.
I made a bin picking game with Python
I made a Mattermost bot with Python (+ Flask)
I made a Python Qiita API wrapper "qiipy"
I made a QR code image with CuteR