node.jsでrssをparseしてみた

# 準備
1. [ExpressでWebアプリケーションを自動生成する](http://qiita.com/kkam0907/items/1e35a72c549e1e3dfabf)
2. feedparserモジュールをインストールする

  ```
  npm install feedparser
  ```

# rssをparseするプログラムコード

routes/feed.js

```js
'use strict';

var express = require('express');
var router = express.Router();
var FeedParser = require('feedparser');
var http = require('http');


router.get('/parse', function(request, response) {
  var feedMeta;
  var episodes = [];

  // 指定urlにhttpリクエストする
  http.get('http://leoville.tv/podcasts/sn.xml', function(res) {
    //レスポンスにフィードパーサをパイプで渡す
    res.pipe(new FeedParser({}))
      .on('error', function(error) {
        response.status(500).json({
          'message': 'HTTP failure while fetching feed'
        });
      })
      .on('meta', function(meta) {
        feedMeta = meta;
      })
      .on('readable', function() {
        var stream = this, item;

        // chunkデータを保存する
        while (item = stream.read()) {
          var ep = {
            'title' : item.title,
            'mediaUrl': item.link,
            'publicationDate': item.pubDate
          };
          episodes.push(ep);
        }
      })
      .on('end', function() {
        // データ保存完了後、jsonに整形する
        var result;
        result = {
          'feedName': feedMeta.title,
          'feedArtist': feedMeta['itunes:author']['#'],
          'website': feedMeta.link,
          'albumArt': {
            'url': feedMeta.image.url,
            'width': parseInt(feedMeta['rss:image']['width']['#']),
            'height': parseInt(feedMeta['rss:image']['height']['#'])
          },
          'episodes': episodes
        };

        // json形式でレスポンスを行う
        response.json(result);
      });
  });
});

module.exports = router;
```

# レスポンスを確認

curl http://localhost:3000/feed/parse

```json
{
    "albumArt": {
        "height": 144, 
        "url": "http://feeds.twit.tv/coverart/sn144audio.jpg", 
        "width": 144
    }, 
    "episodes": [
        {
            "mediaUrl": "http://www.podtrac.com/pts/redirect.mp3/twit.cachefly.net/audio/sn/sn0461/sn0461.mp3", 
            "publicationDate": "2014-06-25T00:47:56.000Z", 
            "title": "SN 461: Your Questions, Steve's Answers 190"
        }, 
        {
            "mediaUrl": "http://www.podtrac.com/pts/redirect.mp3/twit.cachefly.net/audio/sn/sn0460/sn0460.mp3", 
            "publicationDate": "2014-06-18T01:11:38.000Z", 
            "title": "SN 460: Authenticated Encryption"
        }, 
        {
            "mediaUrl": "http://www.podtrac.com/pts/redirect.mp3/twit.cachefly.net/audio/sn/sn0459/sn0459.mp3", 
            "publicationDate": "2014-06-11T01:10:47.000Z", 
            "title": "SN 459: Your Questions, Steve's Answers 189"
        }, 
        {
            "mediaUrl": "http://www.podtrac.com/pts/redirect.mp3/twit.cachefly.net/audio/sn/sn0458/sn0458.mp3", 
            "publicationDate": "2014-06-04T00:37:50.000Z", 
            "title": "SN 458: TrueCrypt: WTH?"
        }, 
        {
            "mediaUrl": "http://www.podtrac.com/pts/redirect.mp3/twit.cachefly.net/audio/sn/sn0457/sn0457.mp3", 
            "publicationDate": "2014-05-28T01:49:42.000Z", 
            "title": "SN 457: Your Questions, Steve's Answers 188"
        }, 
        {
            "mediaUrl": "http://www.podtrac.com/pts/redirect.mp3/twit.cachefly.net/audio/sn/sn0456/sn0456.mp3", 
            "publicationDate": "2014-05-21T03:05:40.000Z", 
            "title": "SN 456: Harvesting Entropy"
        }, 
        {
            "mediaUrl": "http://www.podtrac.com/pts/redirect.mp3/twit.cachefly.net/audio/sn/sn0455/sn0455.mp3", 
            "publicationDate": "2014-05-14T00:09:49.000Z", 
            "title": "SN 455: Your Questions, Steve's Answers 187"
        }, 
        {
            "mediaUrl": "http://www.podtrac.com/pts/redirect.mp3/twit.cachefly.net/audio/sn/sn0454/sn0454.mp3", 
            "publicationDate": "2014-05-07T01:02:29.000Z", 
            "title": "SN 454: Certificate Revocation, Part 2"
        }, 
        {
            "mediaUrl": "http://www.podtrac.com/pts/redirect.mp3/twit.cachefly.net/audio/sn/sn0453/sn0453.mp3", 
            "publicationDate": "2014-04-30T01:10:12.000Z", 
            "title": "SN 453: Certificate Revocation"
        }, 
        {
            "mediaUrl": "http://www.podtrac.com/pts/redirect.mp3/twit.cachefly.net/audio/sn/sn0452/sn0452.mp3", 
            "publicationDate": "2014-04-23T00:49:11.000Z", 
            "title": "SN 452: Your Questions, Steve's Answers 186"
        }
    ], 
    "feedArtist": "TWiT", 
    "feedName": "Security Now (MP3)", 
    "website": "http://twit.tv/sn"
}
```