2004.11.12

.Netで XMLファイルを DataSetに読み込む

.netで XMLファイルを読む方法はいろいろあるが、そのうちもっとも容易と思われる
『ファイルを直接 DataSetに読み込む』という方法を ちかごろ試しに使っている。


例えば、仮の題材として ASP.net での Web.Config を使うとする。

<configuration>
 <system.web>...(略)...</system.web>
 <appSettings>
  <add key="foo" value="VAR" />
 </appSettings>
</configuration>

ASP.netでは 各アプリケーション用に定義した項目を取得するには
それ専用のメソッドを使用するのがもっとも簡単。

string sRetValue= System.Configuration.ConfigurationSettings.AppSettings["foo"];
(上記例では“foo”をキーとして“VAR”を取り出す)


これに相当することを、コード(XMLファイルとして読み込み、DataSetとする)で処理するには、
以下のようにする。

  DataSet ds= new DataSet();
  ds.ReadXml( @"c:\inetpub\wwwroot\hogehoge\Web.Config" );
  DataRow dr= ds.Tables["appSettings"].Select("")[0].GetChildRows("appSettings_add")[0].Table.Select("key='foo'")[0];
  string sRetValue= (dr.ItemArray.GetValue(1)).ToString();

なんと DataSet.ReadXml というメソッドが『<appSettings>』と『<add>』というタグをデータベースの
テーブルに見立てて、親子関係(リレーション:この場合“appSettings_add”と勝手に命名される)が
あるものと自動的に認識してくれるのだ。

本来、厳密には .XSDというスキーマファイルを作成しなくてはいけないが、
なくてもかなりの程度までは柔軟に解釈してくれる。
すばらしい。


・・・しかし、これには欠点があった。
データの構造が以下のようになったとしよう。

<configuration>
 <system.web>...(略)...</system.web>
 <appSettings Page="pg1">
  <add key="foo" value="HOGE" />
 </appSettings>
 <appSettings Page="pg2">
  <add key="foo" value="VAR" />
 </appSettings>
</configuration>


『<appSettings>』を“Page”という条件別に分けたとする。

気持ち的には以下のように『<appSettings>』の“Page='pg2'”で絞った結果だけを取得したい。

DataRow dr= ds.Tables["appSettings"].Select("Page='pg2'")[0].GetChildRows("appSettings_add")[0].Table.Select("key='foo'")[0];
string sRetValue= (dr.ItemArray.GetValue(1)).ToString();

しかし、実際試してみると上記コードの2個目の .Select メソッドは、親テーブルの条件を考慮しないで
再度フル検索をかけるようで、上記例では複数の結果が得られる。
そのままでは期待する2件目の“VAR”ではなく1件目の“HOGE”が取れることになってしまう。


試行錯誤を重ねた結果だが、この症状を回避するには、今のところ下のようなやり方しか見つけていない。

  foreach ( DataRow dr in ds.Tables["appSettings"].Select("Page='pg2'")[0].GetChildRows("appSettings_add")[0].Table.Select("key='foo'") ) {
    if ( dr.GetParentRow("appSettings_add").ItemArray.GetValue(1).ToString() == "pg2" )
      { sRetValue= (dr.ItemArray.GetValue(1)).ToString(); }
  }


つまり、見つけた DataRow の親の Page条件が何なのかをループでまわしながら1件ずつ再度確認するのだ。
なんと不毛な・・・。

もっと良い方法があったら、誰か教えて。

コメントを投稿

(いままで、ここでコメントしたことがないときは、コメントを表示する前にこのブログのオーナーの承認が必要になることがあります。承認されるまではコメントは表示されません。そのときはしばらく待ってください。)

photo
ichikawa