Neutral Scent

App developments & Gadgets

XElementの名前空間指定がいちいち面倒なので

XElementでRSSとかATOMとかXMLをいろいろ読みこむアプリをつくるわけですが、いちいちXNameで名前空間を指定するのが面倒じゃないですか?
(その前にまず、Namespace無しでElementが見つからなくてうぎゃー、とかなるわけですが...)
参考:「一郎さん!」と呼べば、R・田中一郎さんも鈴木一郎さんも返事する。 - 何となく Blog by Jitta

こんな感じ、



string uri = "http://b.hatena.ne.jp/kaorun/atomfeed";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
Observable.FromAsyncPattern<WebResponse>(request.BeginGetResponse, request.EndGetResponse)()
.Select(res => new StreamReader(res.GetResponseStream()).ReadToEnd())
.ObserveOnDispatcher()
.Subscribe(s =>
{
var rss = XElement.Parse(s);
XNamespace xns = "http://purl.org/atom/ns#";
var entries = rss.Descendants(xns + "entry");
var items = entries
.Select((entry) =>
new {
Title = entry.Element(xns + "title").Value,
Link = entry.Element(xns + "link").Value,
Summary = entry.Element(xns + "summary").Value
})
.ToArray();
}
, e => MessageBox.Show(e.ToString()));
で、めんどくさいなぁと思って、XElementのExtension Method(拡張メソッド)を一つ作ってみました。



.Subscribe(s =>
{
var rss = XElement.Parse(s);
var entries = rss.NSDescendants("entry");
var items = entries
.Select((entry) =>
new
{
Title = entry.NSElement("title").Value,
Link = entry.NSElement("link").Value,
Summary = entry.NSElement("summary").Value
})
.ToArray();
}
, e => MessageBox.Show(e.ToString()));



static class NSXElement
{
public static IEnumerable<XElement> NSDescendants(this XElement elm, string name)
{
return elm.Descendants(elm.Name.Namespace + name);
}

public static XElement NSElement(this XElement elm, string name)
{
return elm.Element(elm.Name.Namespace + name);
}

public static IEnumerable<XElement> NSElements(this XElement elm, string name)
{
return elm.Elements(elm.Name.Namespace + name);
}

public static XAttribute NSAttribute(this XElement elm, string name)
{
return elm.Attribute(elm.Name.Namespace + name);
}

public static IEnumerable<XAttribute> NSAttributes(this XElement elm, string name)
{
return elm.Attributes(elm.Name.Namespace + name);
}
}

まぁ、あんまり変わらないですね。
もっとスマートなやり方があればぜひ教えてください...。