前回の失敗。
Jitta:「XDocument って、RSS 2.0 しか解析してくれないの?!」
aetosさん:「名前空間の指定がないからです。」
むはー!単純明快な答え、ありがとうございます。
ということで、仕様を当たります。前々回に、英語の仕様へリンクを張りましたが、日本語に訳してくださっている方がいらっしゃいました。
済みません、これで、前々回にいただいているコメント厳密には名前空間 URI も見た方がいいでしょう。
がわかりました。
名前空間にはバージョン番号が含まれることがあります。現に、Atom は「2005」というのが、2005年に決まったことを表しているでしょうし、RSS 1.0 は、「1.0」と入っています。ここで調べたかったのは、どのフォーマットの系統なのかということなので、そこまで細かいのが必要かなぁ?と思っていたのですが、要るのね。。。
とりあえず、名前空間を指定すれば Element メソッドで取得できるか?確認します。
XElement.Element メソッドに指定するのは、XName クラスです。しかし、XName クラスにはコンストラクタがありません。これは、String クラスからのコンバーターが用意されています。では、名前空間は、どうやって指定するのでしょう?名前空間を定義するときには、名前空間の省略名が定義できます。そういったもので、省略名が変わっていたら、指定できないのでは?
ところが、XName クラスは、省略名を定義できません。全て XName クラスに展開されており、XName クラスでは、完全な名前空間を持っています。では、どのように参照するのでしょう?次のように指定します。
XName name = "{namespace}local name";
では、書き換えます。
static IEnumerable<XElement> GetItems() {
// とりあえず、全部 RSS 1.0
string[] feeds = {
"http://rss.rssad.jp/rss/itmatmarkit/rss2dc.xml",
"http://rss.rssad.jp/rss/news/rss2dc.xml",
"http://rss.rssad.jp/rss/fwin2k/rss2dc.xml",
"http://rss.rssad.jp/rss/fdotnet/rss2dc.xml"
};
foreach (var str in feeds) {
var feed = XDocument.Load(str);
var channel = feed.Root.Element("{http://purl.org/rss/1.0/}channel");
var items = channel.Elements("{http://purl.org/rss/1.0/}item");
foreach (var item in items)
yield return item;
}
}
無事、動きました。
投稿日時 : 2009年6月10日 22:28