FlasherのためのSilverlight入門(4) XML読み込み

次はXMLの読み込みです。

FLASHでの開発で設定情報などを外部のXMLに持たせるのは基本になっていると思うというか、それができないと色々困ります。で、Silverlightでどうするか。

 

System.Net.Linkの参照設定

XMLの処理を行うのに、Linqというライブラリを使うので、まずVisual Studioのプロジェクトにそのライブラリを追加します。Linqについて詳しくはこちら。

 

vs_linksetting.jpgソリューション・エクスプローラー(左パネル)

ソリューション・エクスプローラーの参照設定を右クリック、「参照の追加」を押して、System.Xml.Linqを選びます。 これでとりあえず設定できました。ソースに、using System.Xml.Linq;を加えておきます。

 

XMLの読み込み

今回はSilverlightのアプリに組み込んだXMLではなく外部のファイルをとりにいく前提です。相対パスで書けるといろいろいいのですが、どうもダメっぽい気がします。"./config.xml"なんて指定すると、System.UriFormatExceptionと言われます。できるなら教えてください。

で、以下のようにします。

 

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

 public void loadXml(){
                WebClient wc = new WebClient();
                wc.OpenReadCompleted += wc_OpenReadCompleted;
                wc.OpenReadAsync(new Uri("http://localhost:64771/config.xml"));
        }

        /*
         * XMLが読み込まれたら呼ばれるイベント
    * */
        private void wc_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                System.Diagnostics.Debug.WriteLine("on Read Error");
                System.Diagnostics.Debug.WriteLine(e.Error.Message);
                return;
            }
            using (Stream s = e.Result)
            {
                System.Diagnostics.Debug.WriteLine("success");
                XDocument doc = XDocument.Load(s);
                System.Diagnostics.Debug.WriteLine(doc.ToString(SaveOptions.OmitDuplicateNamespaces));
            }
        } 

とりあえずこれで読んだXMLファイルが出力パネルに表示されます。

 

Linq to XML

XMLへのアクセスにはLinqという機能を使います。これはSQLのような書き方でXMLなどのデータに汎用的にアクセスする方法です。 単純にDOMでアクセスといった方法でなく、「itemという要素のattributesが80以上のものを抽出」、みたいなことが簡単にできるようになっています。

Linqについては詳しくは説明しない(できない)ので、以下のサイトとかを読んでみてください。

ちょっと分かりにくいですが、ぶっちゃけていうと、XDocumentクラスがXMLドキュメント、XElementクラスは一つ一つのタグを示し、XAttributeクラスはそのAttributesを示します。次のXML分から取り出すサンプルを書いてみました。

<?xml version="1.0" encoding="utf-8" ?>
<config>
  <author familyname="tohsaki" firstname="hisayoshi">遠崎寿義</author>
  <linkitem>
    <item key="a1" value="http://blog.tokyoace4.com" />
    <item key="a2" value="http://the.strippers.jp" />
    <item key="a3" value="http://twitter.com/yankeekun/" />
  </linkitem>
</config>

 の中から <item key="a3" value="http://twitter.com/yankeekun/" />のvalueの値を取り出すには次のようにします。


 

 private void wc_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                System.Diagnostics.Debug.WriteLine("on Read Error");
                System.Diagnostics.Debug.WriteLine(e.Error.Message);
                return;
            }
            using (Stream s = e.Result)
            {
                System.Diagnostics.Debug.WriteLine("success");
                XDocument doc = XDocument.Load(s);
                System.Diagnostics.Debug.WriteLine(doc.ToString(SaveOptions.OmitDuplicateNamespaces));

                XElement link_A3 = new XElement("url",
                   from links in doc.Element("config").Element("linkitem").Elements("item")
                   where (string)links.Attribute("key") == "a3"
                   select (string)links.Attribute("value")
                   );
                System.Diagnostics.Debug.WriteLine(link_A3.Value);
            }
        }        

Linq文を実行して、<url>http://twitter.com/yankeekun/</url> というXElementを作っています。

from ~ in の部分は for in みたいな感じで、config.linkitem.item[]の要素を順番に見ていくぞと宣言し、whereでひっかける条件、「keyというattributesが"a3"だったら」ということを書いて、最後にselectで「条件にあったアイテムから取り出す値」を決めているという感じです。

 

ちなみに、このXMLで、authorタグの各情報を取得する場合は次のようになります。

XElement authorInfo = doc.Element("config").Element("author");
System.Diagnostics.Debug.WriteLine("authorInfo");
System.Diagnostics.Debug.WriteLine(authorInfo.Value + "(" + authorInfo.Attribute("familyname").Value + " " + authorInfo.Attribute("firstname").Value + ")");

 

これは、

authorInfo

遠崎寿義(tohsaki hisayoshi)

のように出力されます。
コメントする
トラックバック(0)

トラックバックURL: http://blog.tokyoace4.com/cgi-bin/mt/mt-tb.cgi/151