All posts by Ishisaka

XML to Linq 入門番外編 : XDocumet.Load()でProxyの例外が発生する場合

前回までのサンプルではXDocument.Load(”URL”)でRSSのフィードをロードしてしましたが、Proxy経由でのアクセスが必要な場合に、Loadメソッド実行時に例外が発生します。

Loadメソッドは引数で指定されたURIがhttpであった場合に内部的にWebアクセスしていると思われますが、そのときにProxyに対しては考慮していないようです。また、Loadメソッドの引数やXDocumentのプロパティではProxyの設定をする方法が無いので、このような場合にはLoadメソッドで直接URIを指定するのではなく、Proxyの設定ができるWebClientとXmlReaderを使ってWEBサーバからXMLファイルを取得し、ストリーム化し、最終的にXMLデータとして取得する必要があります。

以下がそのサンプルです。

using System.Xml;
using System.Net;
using System.IO;

WebClient web = new WebClient();
WebProxy myProxy = new WebProxy("proxy:8080", true);
myProxy.Credentials = CredentialCache.DefaultCredentials;
web.Proxy = myProxy;
Stream stream = web.OpenRead(@"http://www.isisaka.com/blog/index.xml");

XmlReader reader = XmlReader.Create(stream);


//XDocument rss = XDocument.Load(@"http://www.isisaka.com/blog/index.xml");
XDocument rss = XDocument.Load(reader);

5行目でWebClientクラスのインスタンスを作ります。

6行目でWebProxyクラスのインスタンスを作り、Proxyサーバアドレス等を設定し、7行目でそのProxyの認証のタイプを設定します。(この場合はNTLM認証です)

8行目でWebClientのインスタンスにProxyを設定します。

9行目ではWEBサーバよりXMLデータをStreamとして取得します。

11行目ではstreamになっているXMLデータをXmlReaderに変換します。

15行目でLinq to XMLでXMLデータを使用できるようにXmlReaderからXDocumentにXMLデータをロードします。

XDocumentクラスのLoadメソッドでのURI指定は便利ですが、ネットワーク環境によってはこのような処理が必要になるので注意してください。また今回特に例外処理を入れてないのですが、実際には部分部分で例外処理が必要になる場合があるのでその注意もお願いします。

.NETでのProxy設定については以下のKBが参考になります。

[PRB] HTTP プロキシ サーバー経由で Web サービスを使用する .NET クライアントでエラーが発生する

http://support.microsoft.com/kb/318140/

早いところ次回が書けるといいなぁ。ではまた次回!

Liunq to XML 入門 その3 (Linq クエリ構文)

今回は予定を変えてLinqのクエリ式の構文について説明します。前回クエリの方法について説明しましたが、クエリ式の構文についての説明はしていなかったので、前回説明した基本的なクエリ式の構文について説明します。

基本的なクエリ

Linqでの基本的なクエリ式は以下のようになります。

from [範囲変数] in [データソース]
select [範囲変数]

まず、クエリ式はfrom句から始める必要があります。つぎに最低でもselect句で範囲変数を指定し、最終的に式が返すソースシーケンスの内容を確定します。

from句

from [範囲変数] in [データソース]

from句ではクエリもしくはサブクエリの対象となるデータソースとソースシーケンス内の各要素を表すローカルの範囲変数を指定します。ソースシーケンスとはデータソースの中でLinq式内での各操作の対象となる連続したデータのことです。

LinqのデータソースにはIEnumerable<T>インターフェイスあるいはIEnumerableとその派生インターフェイスを実装したオブジェクトだけを指定することができます。通常の配列やArrayList、ADO.NETのデータセットはIEnumerableインターフェイスを持つのでLinqの対象とすることができます。

selsct句

select [式]

selsct句はクエリ式が実行されたときに生成される値の型を指定します。クエリ式の結果はselect句の前の式の評価およびselect句の式の評価によって生成されます。

select句の一番単純な例は式に範囲変数を指定し、ソースシーケンスをそのまま式の値にすることですが、以下の例のようにこの式でデータ変換をすることができます。

XDocument rss = XDocument.Load(@"http://www.isisaka.com/blog/index.xml");   
//select句でデータ変換する   
IEnumerable query = from x in rss.Element("rss").Elements("channel").Elements("item")
                              select DateTime.Parse(x.Element("pubDate").Value);   
foreach (var d in query) {   
    Console.WriteLine(d.ToLongDateString());   
}

この例では4行のselect句の式でXMLのバリュー(string型)のデータをDateTime型に変換しているので、クエリ式の結果をIEnumerble<DateTime>型の変数に格納することができます。

条件付きクエリ

先ほどのもっとも単純なクエリ式ではソースシーケンスのデータに対し、なんのフィルタリングもかけずに値を返していましたが、実際には何らかのフィルタリング条件をつけて必要なデータだけをソースシーケンスから取り出したいことが多いと思います。

クエリ式において、このフィルタリング条件を指定するのがwhere句です。

from [範囲変数] in [データソース]
whewe [条件式]
select [式]

この例では7秒目でToListメソッドを使ってLinq式の結果をメモリ上に確定しています。

これの詳しい話についてはMSDNライブラリの「クエリの結果をメモリに格納する (C# プログラミング ガイド)」を参照してください。

それでは、また次回。

Linq to XML 入門その2 (基本的ななクエリー)

それでは、Linqでの基本的なクエリーの方法について説明していきます。

今回はXMLデータとして、このBlogのRSS 2.0フィードを利用します。

では、まずRSSを表示してみましょう。

Document rss = XDocument.Load(@"http://www.isisaka.com/blog/index.xml");
Console.WriteLine(rss.Declaration);
//Console.WriteLine(rss.FirstNode);
Console.WriteLine(rss);

その表示結果の一部。


    
        
            OPC Diary
            http://www.isisaka.com/blog/
            私的ソフトウェア開発あれこれ。
            ja
            Copyright 2009
            Thu, 14 May 2009 10:47:36 +0900
            http://www.sixapart.com/movabletype/
            http://blogs.law.harvard.edu/tech/rss
            
                プログラム言語 Axum
                
                    Axum

.NET Framework上でEr langっぽい(ぽいねあくまでも)並列言語実行環境を提供するプログラミング言語。Erlangっぽいので、基本的にメッセージパッ シングで実行単位(Agentというらしい)間でデータ交換を行うようだ。

これがこのまま製品化するとは思わないけど、 まぁF#の例もあるので、案外化けるかもだ。素直に考えればC#に取り込まれていくんだろうけど。

]]>
http://www.isisaka.com/blog/archives/2009/05/_axum.html http://www.isisaka.com/blog/archives/2009/05/_axum.html .NET オブジェクト指向・システム開発 Thu, 14 May 2009 10:47:36 +0900

RSSフィードを受信して、表示できる事が確認できたでしょうか。

では、このデータからBlog記事の投稿日とタイトルの一覧を作りたいと思います。

RSS 2.0ではitemエレメントに各Blog記事のデータが入っています。

XDocument rss = XDocument.Load(@"http://www.isisaka.com/blog/index.xml");
//XMLの木構造をたどって目的のElementに到達するやり方
var query = from x in rss.Element("rss").Elements("channel").Elements("item")
            select x;
foreach (var i in query) {
        DateTime pubDate = DateTime.Parse(i.Element("pubDate").Value);
        Console.WriteLine(pubDate.ToString() + "\t: " + i.Element("title").Value);

1行目ではRSSフィードを取り出しています。

3行目でLinqを使いRSSフィードからitemエレメントを取り出します。ここではRoorのrssエレメントから純にRSSの木構造たどってitemeエレメントまでを指定し検索もとを絞っています。itemエレメントは一つとは限らないのでElementsとして指定します。

5行目以降では検索結果をもとに更新日とタイトルをリスト表示します。

この様に特定のエレメントを検索対象とするには性格に木構造をたどる形で指定していく必要があり、その木構造が深いと指定するのが大変です。

そこで、Linq to XMLではDescendantsでエレメント名を指定すれば木構造をたどらずにダイレクトに指定する事が出来ます。(Descendantの意味は子孫)

XDocument rss = XDocument.Load(@"http://www.isisaka.com/blog/index.xml");
//Descendantsを使う方法
var query = from x in rss.Descendants("item")
            select x;
foreach (var i in query) {
    DateTime pubDate = DateTime.Parse(i.Element("pubDate").Value);
    Console.WriteLine(pubDate.ToString() + "\t: " + i.Element("title").Value);
}

先ほどと変わったのは3行目です。かなりスッキリ書けるようになったのがわかると思います。

2009/05/14 10:47:36     : プログラム言語 Axum
2009/05/11 19:03:02     : 第2回静岡 IT Pro 勉強会のご案内
2009/05/10 21:53:00     : 第30回 NT-Committee2関東勉強会
2009/05/10 21:21:41     : プリンタを買いました。(HP C309a)
2009/05/10 9:57:29      : キヤノン インクジェットプリンタのヘッド交換ができないので買い換えてやる!
2009/05/10 8:20:50      : そろそろCorei7かな。。
2009/05/10 0:06:41      : デザイナー目線でのFlash vs. Silverlight(2)
2009/05/09 15:42:19     : Linq to XML 入門その1 (XML文書の作り方)
2009/05/08 12:16:11     : Japan Windows Server : Hyper-V Server R2 Release Candidate 公開
2009/05/08 7:34:02      : Windows 7 向けリモートサーバ管理ツール
2009/05/06 23:34:56     : exFATはやはりブートメディアを作ることはできない
2009/05/05 15:48:55     : Vistaの供給は2011年1月まで、メインストリームサポートは2012年4月までらしい
2009/05/05 15:12:37     : Windows 7 RC アメリカでは一般公開
2009/05/04 23:32:40     : Windows 7(x64) をVirtualBoxに入れてみた。
2009/05/02 6:43:33      : プログラミングに適したフォント

表示結果はこうなります。

それでは、where句を使った条件検索を試してみます。

以下のコードでは5/11以降に更新された記事のリストを表示するようにします。

XDocument rss = XDocument.Load(@"http://www.isisaka.com/blog/index.xml");
//Descendantsを使う方法
var query = from x in rss.Descendants("item")
            where DateTime.Parse(x.Element("pubDate").Value) > DateTime.Parse("2009/5/11")
            select x;
foreach (var i in query) {
    DateTime pubDate = DateTime.Parse(i.Element("pubDate").Value);
    Console.WriteLine(pubDate.ToString() + "\t: " + i.Element("title").Value);
}

4行目のwhere句で5/11以降のデータのみ抽出するようにしています。

以下が実行結果です。

2009/05/14 10:47:36     : プログラム言語 Axum

11日以降に投稿した記事のリストが表示されています。

今回はここまで。

RSSを加工したい事はよくあるので、少しぐらいは参考になったでしょうか。

次回はもう少し複雑なクエリについて説明したいと思っています。ただ、データを作るのが難儀なのでしばらくお待ちください。。。

Linq to XML 入門その1 (XML文書の作り方)

準備

これから数回に分けてLinq to XMLの基礎的な使い方についてまとめていきます。

これらの記事に書かれているコードは特に明記がない場合は以下の環境で試験をしています。

  • Visual Studio Team Systeme 2008 Team Suite SP1
  • .NET Framework 3.5 SP1
  • Windows Vista Ultimate x64 ENU

また特に断らない限り使用するプロジェクトテンプレートはコンソールアプリケーションです。

Visual StudioはTeam Suiteを使っていますが、記事に書かれている内容はC# Express Editionでも問題ないはずです。

注意点

これからの記事では入門と言っておきながら、Linqの詳細な仕様や、XML自体の説明はしません。

Linq to XML各クラスの細かい説明はせずに、実際に最低必要だと思う事のみコードと説明をしていくので、各クラスが持つメソッドやメンバーの詳細についてはMSDNライブラリを参照してください。忘れなければ記事中に適宜リンクしていきます。

まずはこれが無くっちゃ始まらない

using System.Xml.Linq;

忘れずにusing句でLinq to XMLの名前空間を呼び出しておきましょう。また、Visual Studioのソリューションエクスプローラで参照設定を確認し、System.XML.Linqの参照設定がない場合には追加します。

最も単純例

最も簡単にXMLのデータを作成し、コンソールに表示させたいと思います。

var x = new XElement("Name", "Tadahiro Ishisaka");
Console.WriteLine(x);

ここでは単純にNameという1種類のエレメントを持つXMLデータを作成し、コンソールに表示させています。

XElementというクラスがLinq to XMLではXMLエレメントを表すクラスになります。

ちなみにLinq to XMLの各クラスは頭にXがつきます。

出力結果はこうなります。

Tadahiro Ishisaka

次にXMLのエレメントに属性(Attribute)を追加してみます。

var x = new XElement("Name", new XAttribute("ID", 99999), "Tadahiro Ishisaka");
Console.WriteLine(x);

今度はXElemntクラスのコンストラクタの中でXAttributeクラスを初期化し、IDという属性とその値として99999を追加しています。

出力結果はこうなります。

Tadahiro Ishisaka

NameエレメントにID属性が追加され、その値が99999となっているのがわかると思います。

また、このコードはXElementクラスのAddメソッドを使用して、以下のように記述しても同じ結果になります。

var x = new XElement("Name", "Tadahiro Ishisaka");
x.Add(new XAttribute("ID", 99999));
Console.WriteLine(x);

ここまでで、今まで.NETでXMLデータを処理されてきたかたには、かなりコーディング量が減って、楽にコードを書けていることがわかると思います。

Continue reading Linq to XML 入門その1 (XML文書の作り方)