Help us understand the problem. What is going on with this article?

[C# / LINQ to XML] すぱこーRSSフィードからデータを取得してみよう

More than 3 years have passed since last update.

こんにちはー!ニアです。

今回はC#とLINQ to XMLを使って「すぱこー RSS フィード | プログラミング生放送」のRSSフィードから、チャンネル情報と各話のデータを取得していきます。

1. すぱこーRSSフィードの構成

すぱこー RSS フィード | プログラミング生放送」にある要素の一覧より、RSSフィードの構成は以下のようになっています。

すぱこーRSSフィードの構成
<rss version="2.0" xmlns:p="http://pinga.mu/terms/" xmlns:media="http://search.yahoo.com/mrss/" xmlns:dcndl="http://ndl.go.jp/dcndl/terms/" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>作品タイトル</title>
    <link>作品の URL</link>
    <description>作品の説明</description>
    <pubDate>最新話の公開日(RFC 822規定の日付形式)</pubDate>
    <image>作品のバナー画像 URL</image>
    <dc:creator>作者名</dc:creator>
    <item>
      <title>タイトル</title>
      <dc:creator>作者名</dc:creator>
      <link>作品の URL</link>
      <pubDate>公開日(RFC 822規定の日付形式)</pubDate>
      <description>あらすじ</description>
      <dcndl:volume>話数</dcndl:volume>
      <dc:modified>投稿記事の更新日(RFC 822規定の日付形式)</dc:modified>
      <p:isAvailable>利用可能かどうか(通常はtrue)</p:isAvailable>
      <media:content url="漫画画像 URL"></media:content>
      <media:thumbnail url="漫画サムネイル URL"></media:thumbnail>
      <guid isPermaLink="false">ID</guid>
    </item>
    <item>
    ...
    </item>
    ...
  </channel>
</rss>

2. LINQ to XMLとは?

LINQ(Language Integrated Query)とは、リストやデータベース、XMLなどの操作(要素の列挙や抽出、統計などのクエリ機能)をプログラミング言語から利用できる機能です。

LINQ to XMLは、XMLデータに対してLINQを利用することができます。

3. C#とLINQ to XMLですぱこーRSSフィードを取得してみよう

今回はコンソールアプリで、すぱこーRSSフィードの取得し、データを出力していきます。

LINQ to XMLを利用するには、System.Xml.Linq名前空間を使用します。

SpacoFeedTrial.cs
using System;
using System.Collections.Generic;
using System.Xml.Linq;

class Program {

    static void Main( string[] args ) {
        // すぱこーRSSフィードのURLです。(最新の5話分だけ取得します)
        string url = @"http://pronama-api.azurewebsites.net/feed/spaco?count=10";
        // すぱこーRSSフィードで使用している名前空間です。
        XNamespace p = @"http://pinga.mu/terms/";
        XNamespace media = @"http://search.yahoo.com/mrss/";
        XNamespace dcndl = @"http://ndl.go.jp/dcndl/terms/";
        XNamespace dc = @"http://purl.org/dc/elements/1.1/";

        Console.Write( "すぱこーRSSフィードの取得中... " );
        try {
            // すぱこーRSSフィードを読み込みます。

            Console.WriteLine( "完了!" );

            // すぱこーRSSフィードのデータの取得&出力します。

        }
        catch( Exception ex ) {
            Console.WriteLine( $"エラー : {ex.Message}" );
        }

    }
}

3.1. RSSフィードを読み込む

まず、XElementクラスLoadメソッドでRSSフィードを読み込みます。

すぱこーRSSフィードの読み込み
// すぱこーRSSフィードを読み込みます。
XElement spx = XElement.Load( url );

※読み込むRSSフィードのデータサイズが大きいと、時間がかかります。

3.2. RSSフィードからチャンネル情報を取得する

RSSフィードを読み込んだら、チャンネル情報と各話のデータを取得していきます。

チャンネル情報はchannel要素内にあります。XElementクラスのElementメソッドでchannel要素を取得します。

channel要素の取得
// すぱこーRSSフィードのデータの取得&出力します。
XElement spxChannel = spx.Element( "channel" );

取得したchannel要素から、XElementクラスのElementメソッド(XMLDOMでいうSelectSingleNodeです)でチャンネル情報の各要素を取得し、Valueプロパティでデータを取り出します。

※Valueプロパティの戻り値の型は文字列(string)です。

また、RSSフィードで使われている日付の文字列はRFC 822」の日付形式となっており、DateTime構造体ParseメソッドでDateTime型に変換することができます。

channel要素からチャンネル情報を取得
// チャンネル情報を取得します。
Console.WriteLine( $"タイトル : {spxChannel.Element( "title" ).Value}" );
Console.WriteLine( $"概要 : {spxChannel.Element( "description" ).Value}" );
Console.WriteLine( $"最終更新日 : {DateTime.Parse( spxChannel.Element( "pubDate" ).Value )}" );
Console.WriteLine( $"リンク : {spxChannel.Element( "link" ).Value}" );

3.3. LINQを使って、各話のデータを取得する

各話のデータはitem要素内にあります。XElementクラスのElementsメソッド(XMLDOMでいうSelectSingleNodeです)でitem要素のコレクションを取得します。

item要素のコレクションを取得
// 各話のデータを取得します。
IEnumerable<XElement> spxItems = spxChannel.Elements( "item" );

取得したitem要素のコレクションはIEnumerable<XElement>型なので、LINQを利用することができます!

ここではforeach文でコレクションの各要素(XElement型)を列挙し、各話のデータを取得してコンソール画面に表示します。

XElementクラスのElementメソッド及びElementsメソッドで、名前空間付きの要素を指定する時には、「名前空間名(XNamespace型)」と「要素名(XName型)」を加算演算子(+)で結合した文字列を使用します。

各話のデータを取得して表示
Console.WriteLine( "\n各話の情報" );
foreach( var item in spxItems ) {
    Console.WriteLine( $"◆ 第{int.Parse( item.Element( dcndl + "volume" ).Value )}話" );
    Console.WriteLine( $" タイトル : {item.Element( "title" ).Value}" );
    Console.WriteLine( $" 作者 : {item.Element( dc + "creator" ).Value}" );
    Console.WriteLine( $" 公開日 : {DateTime.Parse( item.Element( "pubDate" ).Value )}" );
    Console.WriteLine( $" リンク : {item.Element( "link" ).Value}" );
}

完成したプログラムを以下に示します。

SpacoFeedTrial.cs
using System;
using System.Collections.Generic;
using System.Xml.Linq;

class Program {

    static void Main( string[] args ) {
        // すぱこーRSSフィードのURLです。(最新の5話分だけ取得します)
        string url = "http://pronama-api.azurewebsites.net/feed/spaco?count=5";
        // すぱこーRSSフィードで使用している名前空間です。
        XNamespace p = @"http://pinga.mu/terms/";
        XNamespace media = @"http://search.yahoo.com/mrss/";
        XNamespace dcndl = @"http://ndl.go.jp/dcndl/terms/";
        XNamespace dc = @"http://purl.org/dc/elements/1.1/";

        Console.Write( "すぱこーRSSフィードの取得中... " );
        try {
            // すぱこーRSSフィードの読み込みます。
            XElement spx = XElement.Load( url );
            Console.WriteLine( "完了!" );

            // すぱこーRSSフィードのデータの取得&出力します。

            // チャンネル情報を取得します。
            XElement spxChannel = spx.Element( "channel" );

            Console.WriteLine( $"タイトル : {spxChannel.Element( "title" ).Value}" );
            Console.WriteLine( $"概要 : {spxChannel.Element( "description" ).Value}" );
            Console.WriteLine( $"最新話公開日 : {DateTime.Parse( spxChannel.Element( "pubDate" ).Value )}" );
            Console.WriteLine( $"リンク : {spxChannel.Element( "link" ).Value}" );

            // 各話のデータを取得します。
            IEnumerable<XElement> spxItems = spxChannel.Elements( "item" );
            Console.WriteLine( "\n各話の情報" );
            foreach( var item in spxItems ) {
                Console.WriteLine( $"◆ 第{int.Parse( item.Element( dcndl + "volume" ).Value )}話" );
                Console.WriteLine( $" タイトル : {item.Element( "title" ).Value}" );
                Console.WriteLine( $" 作者 : {item.Element( dc + "creator" ).Value}" );
                Console.WriteLine( $" 公開日 : {DateTime.Parse( item.Element( "pubDate" ).Value )}" );
                Console.WriteLine( $" リンク : {item.Element( "link" ).Value}" );
            }

        }
        catch( Exception ex ) {
            Console.WriteLine( $"エラー : {ex.Message}" );
        }

    }
}

実行結果

すぱこーRSSフィードの取得中... 完了!
タイトル : すぱこー
概要 : 高校生の暮井 慧(プロ生ちゃん)と、部活「情報処理研究会」のメンバー 戸増千由莉とフィネス・ヒルヴィレッジが活躍する Web 4コマ漫画「すぱこー」!
最新話公開日 : 2015/11/15 21:30:39
リンク : http://pronama.azurewebsites.net/tag/spaco/

各話の情報
◆ 第41話
 タイトル : すぱこー Ver. 41
 作者 : 池村ヒロイチ
 公開日 : 2015/11/15 21:30:39
 リンク : http://pronama.azurewebsites.net/2015/11/15/web-comic-spaco-41/
◆ 第40話
 タイトル : すぱこー Ver. 40
 作者 : 池村ヒロイチ
 公開日 : 2015/11/04 23:13:28
 リンク : http://pronama.azurewebsites.net/2015/11/04/web-comic-spaco-40/
◆ 第39話
 タイトル : すぱこー Ver. 39
 作者 : 池村ヒロイチ
 公開日 : 2015/10/07 13:16:36
 リンク : http://pronama.azurewebsites.net/2015/10/07/web-comic-spaco-39/
◆ 第38話
 タイトル : すぱこー Ver. 38
 作者 : 池村ヒロイチ
 公開日 : 2015/10/03 23:41:44
 リンク : http://pronama.azurewebsites.net/2015/10/03/web-comic-spaco-38/
◆ 第37話
 タイトル : すぱこー Ver. 37
 作者 : 池村ヒロイチ
 公開日 : 2015/08/18 22:38:46
 リンク : http://pronama.azurewebsites.net/2015/08/18/web-comic-spaco-37/

それでは、See you next!

関連サイト

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away