Blogengine.Netには、ブログロールというRSSリーダーともいうべき機能があり、ぶりちゃんも、ブログリンクとして、おもにPSUぶろぐなどで使用しています。
ただのリンクだけではなく、RSSを読み取って、最新の任意の件数を表示できるのは便利だと思います~
ただ、一部のブログシステムのRSSをうまく認識できないようです。
てっきり、ATOM関連が入ってるかなと思いましたが・・・まったくの検討はずれ(ぉい
まずは、コードをよーく見てみるために、どこにあるか探してみると・・・
App_Code/Controls/Blogroll.cs
にありました。
ここのProcessResposeメソッドで取得したRSSをチェック、それぞれのリストに入れているようですねぇ。
ぶりちゃんは、RSS 2.0のXML構造しか頭になかったので、このソースだとふつーにとおるなぁ・・・と思っていたのですが・・・
デバッグでRSSが読めないデータを追っていくと、構造が違う・・・
RSS 1.0の構造でした・・・^^;
タグの名称からして全く違うので、そりゃ認識するはずもないな^^;
いろいろ試行錯誤するにもうまくいかず・・・ネット上を探してみることに・・・
すると、C#でコードサンプルがあるじゃないですか・・・
(参考にしたブログはこちらです。)
ATOMは組み込んでいませんが、RSS1.0も読めるように、Blogrollを調整していきます。
App_Code/Controls/Blogroll.csの、ProcessResposeメソッドに、RSS1.0、2.0の判別を追加し、RSS 2.0なら既存の処理を、RSS 1.0の場合は新規に処理を追加しました。
尚、コードはあまりいい処理はしていないとおもいます^^;
参考にするも、そのまま貼り付けるにも・・・自己責任で~
/// <summary>
/// Gets the request and processes the response.
/// </summary>
private static void ProcessRespose(IAsyncResult async)
{
blogRequest blogReq = (blogRequest)async.AsyncState;
try
{
using (HttpWebResponse response = (HttpWebResponse)blogReq.Request.EndGetResponse(async))
{
XmlDocument doc = new XmlDocument();
doc.Load(response.GetResponseStream());
XmlNodeList nodes;
if (GetRSSKind(doc) == "rdf:RDF")
{
//rss 1.0
XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
string ns = GetRSS1NameSpace(doc, "xmlns");
string nsrdf = GetRSS1NameSpace(doc, "xmlns:rdf");
nsmgr.AddNamespace("rdf", nsrdf);
nsmgr.AddNamespace("empty", ns);
nodes = doc.SelectNodes("rdf:RDF/empty:item", nsmgr);
foreach (XmlNode node in nodes)
{
string title = node.SelectSingleNode("empty:title", nsmgr).InnerText;
string link = node.SelectSingleNode("empty:link", nsmgr).InnerText;
DateTime date = DateTime.Now;
if (node.SelectSingleNode("empty:pubDate", nsmgr) != null)
{
date = DateTime.Parse(node.SelectSingleNode("empty:pubDate", nsmgr).InnerText);
}
blogReq.ItemTitles.Add(title);
blogReq.ItemLinks.Add(link);
}
}
else
{
//通常のrss 2.0用
nodes = doc.SelectNodes("rss/channel/item");
foreach (XmlNode node in nodes)
{
string title = node.SelectSingleNode("title").InnerText;
string link = node.SelectSingleNode("link").InnerText;
DateTime date = DateTime.Now;
if (node.SelectSingleNode("pubDate") != null)
{
date = DateTime.Parse(node.SelectSingleNode("pubDate").InnerText);
}
blogReq.ItemTitles.Add(title);
blogReq.ItemLinks.Add(link);
}
}
}
}
catch
{
}
}
RSS1.0の場合、rdf名前空間がありますので、通常のSelected(Single)Node(s)では取得できません。
XMLNamespaceManagerを作成し、必要な名前空間を指定する必要があるようです。
名前空間をXML内部から取得するためのメソッドや、RSSのバージョンを判別するメソッドはこのような感じに書いてみました。
private static string GetRSSKind(XmlDocument xml)
{
foreach (XmlNode xmlNode in xml.ChildNodes)
{
if (xmlNode.Name == "rdf:RDF") return xmlNode.Name;
if (xmlNode.Name == "rss") return xmlNode.Name;
}
return "";
}
private static string GetRSS1NameSpace(XmlDocument xml, string ns)
{
foreach (XmlNode xmlNode in xml.ChildNodes)
{
if (xmlNode.Name == "rdf:RDF") return xmlNode.Attributes.GetNamedItem(ns).InnerText;
}
return "";
}
これは、ProcessResposeメソッドの後に追加しています。
これで、livedoorやfc2など、RSS1.0を使用しているブログでも、ブログロールで記事を正常に表示することができました^^
余談ですが・・・ProcessResposeメソッドでItem項目を取得する際、PubDateをチェックしていますが・・・チェックしているだけなのはなぜだろう(ぉ
上記の変更を反映したブログロールコントロールは以下よりダウンロードできます。
反映方法は、ファイル内のreadme_ja.txtをご覧ください。
公開終了
新バージョンをつくりましたので、そちらをおつかいくださいませ。
新バージョンの記事はこちら