前回までで見た目は、オリジナルのほうに近づいてきた。
今回は、WPFとは一切関係ない部分。RSSを取得する処理を書いていこうと思う。
今回作ってるRSS Readerに必要そうなデータについて検討する。
とりあえず画面から落とし込んでいってみよう。
RSS一覧に表示されているのがアプリに登録されているRSSになる。
アプリとして保持する情報には、タイトルとURLが最低でも必要だろう。
RSSの記事は、1つのRSSに対して複数ある。
記事一覧に表示する項目としては、「日付」「タイトル」「リンク」の3つが必要になる。
扱うデータが固まってきたので、ソリューションにRssReaderLibという名前でライブラリプロジェクトを新規作成して、そこにクラスを定義する。
using System;
namespace RssReaderLib
{
/// <summary>
/// RSSの記事
/// </summary>
public class RssItem
{
public DateTime Date { get; set; }
public string Title { get; set; }
public Uri Link { get; set; }
}
public class RssInfo
{
public string Title { get; set; }
public Uri RssUrl { get; set; }
public RssItem[] Items { get; set; }
}
}
単純なクラスなので、説明はいらないだろう。
さて、ここにRSSから取得したデータを突っ込む処理を書かないといけないのだけど、.NETでどうやるんだ?と思って調べてみた。
なるべく自前でRSS解析なんてことはやりたくない!!
軽く調べた感じでは、下のようなやり方があるっぽい。
- LINQ to XMLで頑張る
- RSS.NETというものを使う
- WCFを使ってみる
1は、自前でRSS解析とほとんど同じなので却下!!RSSが1種類ならいいけど、色々な種類があるので実装は簡単だけどメンドクサイの部類に入る。
2は、結構大丈夫そう。ただ、.NET Framework1.0か1.1のときに作られたみたい?なのと、最近あんまりHOTに活動してなさそうに見えるのでちょっと心配。でもサポートしてるRSSのバージョンは多い。
3は、RSS2.0とAtom1.0をサポートしてるみたい。RSSの配信についてMSDNで熱く語られてる所にこっそりと「フィード フォーマッタ クラスは、オブジェクト モデルの RSS 2.0 と Atom 1.0 に対する双方向のシリアル化をサポートしています。」と書かれている。
ちょっと悩んで2にしようかと思ったけど、今回は3を使って実装してみようと思う。
RssReader側から使うための、メソッドとかを決める。とりあえずは、Uriを受け取ってRssInfoを返すくらいのシンプルなのにしておこう。
using System;
namespace RssReaderLib
{
public class RssReader
{
public RssInfo Read(Uri uri)
{
return null; // とりあえず
}
}
}
ここに中身を実装していく。
System.ServiceModel.Syndication.SyndicationFeedクラスを使うために、System.ServiceModel.Web.dllを参照に追加しておく。
SyndicationFeedクラスの使い方はとっても簡単。SyndicationFeed.Load(XmlReader)みたいにして、XmlReaderから作成できる。
後はプロパティから適当に値をとっていけば大丈夫だろう!ということで早速実装。
using System;
using System.Xml;
using System.ServiceModel.Syndication;
using System.Linq;
namespace RssReaderLib
{
public class RssReader
{
public RssInfo Read(Uri uri)
{
var feed = LoadFeed(uri);
return new RssInfo
{
RssUrl = uri,
Title = feed.Title.Text,
Items = (from item in feed.Items
let link = item.Links.FirstOrDefault() ?? new SyndicationLink(new Uri("about:blank"))
select new RssItem
{
Title = item.Title.Text,
Date = item.PublishDate.DateTime,
Link = link.Uri
}).ToArray()
};
}
private SyndicationFeed LoadFeed(Uri uri)
{
using (var reader = XmlReader.Create(uri.AbsoluteUri))
{
return SyndicationFeed.Load(reader);
}
}
}
}
RssReaderLibTestというプロジェクトを作って、簡単なテストコードをこさえてみて動作確認をしてみた。
using System;
using RssReaderLib;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
// RSSを読み込んで
var info = new RssReader().Read(new Uri("http://blogs.wankuma.com/kazuki/Rss.aspx"));
Console.WriteLine(info.Title);
// 記事の一覧を出力
foreach (var item in info.Items)
{
Console.WriteLine("{0}:{1}:{2}", item.Date, item.Title, item.Link);
}
}
}
}
実行結果は、下のような感じ。
かずきのBlog
2008/04/12 16:14:00:[Other]面白い!!:http://blogs.wankuma.com/kazuki/archive/2008/04/12/132891.aspx
2008/04/11 6:31:00:[Other]消えたorz:http://blogs.wankuma.com/kazuki/archive/2008/04/11/132655.aspx
2008/04/09 23:36:00:[C#][WPF]RSS Reader(簡易版)を作ってみよう! その3:http://blogs.wankuma.com/kazuki/archive/2008/04/09/132477.aspx
2008/04/09 1:05:00:[C#]ラムダ式の中でyieldしたいよね!:http://blogs.wankuma.com/kazuki/archive/2008/04/09/132322.aspx
2008/04/07 23:49:00:[WPF][C#]RSS Reader(簡易版)を作ってみよう! その2:http://blogs.wankuma.com/kazuki/archive/2008/04/07/132122.aspx
2008/04/07 0:10:00:[C#][WPF]RSS Reader(簡易版)を作ってみよう! その1:http://blogs.wankuma.com/kazuki/archive/2008/04/07/131957.aspx
2008/04/05 0:53:00:[C#][WPF]HeaderedContentControlを見てみよう:http://blogs.wankuma.com/kazuki/archive/2008/04/05/131767.aspx
2008/04/04 0:40:00:[C#][WPF]BindingのRelativeSourceの設定色々:http://blogs.wankuma.com/kazuki/archive/2008/04/04/131541.aspx
2008/04/03 0:00:00:[WPF][C#]WPFでAccessチックなリサイズ可能コンボボックスを作ってみよう:http://blogs.wankuma.com/kazuki/archive/2008/04/03/131369.aspx
2008/04/01 23:47:00:[C#][WPF]ContentPresenterを試そう:http://blogs.wankuma.com/kazuki/archive/2008/04/01/131174.aspx
大丈夫っぽい。
次回は、これを使って取得したRSSの情報を、WPFで作った画面に紐付けてみようと思う。