2021年7月2日金曜日

C# 慣れない C# で ReadXml のドタバタ

VB.net を使って来ましたが、
将来の .Net Core や .Net では C# しか使え無くなる様なので、
そろそろ、遅れ馳せ乍ら、C# を覚え様と。
またもや、お勉強 のスタート。


C# の お勉強 。  其処で、ぶち当たった壁!。
ReadXml で Data が入って来ない! です。

.xml 形式でデータを揃え、
一覧形式で表示・選択し、
別のアプリを起動させ様と言う 魂胆 ... 。

以前にも、VB.net で書いてあった汎用の雛形を、
用途に合わせてカスタマイズし、
将来、Windows でも Linux(Ubuntu) でも使いたい。

Python も候補として考えてはいたのですが、
Mono や Visual Studio の流れ から、
将来的には、同様(同一)なソースを UI のみの変更 (GDI+ > GTK3) で賄えるのでは?、
との発想です。
ともすれば、ビルドのみ や 同一バイナリで 賄える時代が来るのかも。

 (現行なら、Linux 上に Mono 導入 & 其れ経由 で、同一バイナリでの運用も可能。)
 (無論、現状では、環境の違いを吸収する書き方が前提ですけれど ... 。)

其の為には、VB.net で書いていたのでは、行く先が不安!。
なので、慣れない C# で、です。


C# 、やはり、勝手が違います。
VB.net で、 C# から Code を移植した経験はありますが、
自分で書くのは 初めて!。

コメントが ' では無く // とか、
文末に ; が必要とか、
Sub が void になるとか、
Dim var As String が string var になるとか、
其の辺からして、 まごまご ... です。

笑って下さい。 X(

差し当たり、簡単な Form を選択して、書き出しました。
現状、Mono を使う予定があるなら、WPF は駄目そうですし。
さて、其れだけなら 投稿 に等、する気は無かったのですが、
其処で、出て来たのが、冒頭に書いた ReadXml で データが入ら無い !。

参りました。
久ぶりの コーディング ですから、勘も鈍っていて、散々です。

試験用のデータなので、其処の最後に置いた コピペ用の Block(Row) に 落とし穴!。

はい。
.xml から Read して行く訳ですが、
Schema を推測する事は出来無い為、
事前に DataTable に Column を定義しますが、
年を表す4桁の数値の為、typeof(int) にしています。
でも、.xml 中では <Year></Year> だったのです。

  null 若しくは "" から、数値変換 で コケてる 感じ。
  朧な記憶では、VB.net と C# とでは、此の辺り の挙動が異なっていた様な ... 。
  後日、検索したのですが、答えには辿り着けず ... 。

不正データ照合!。

此の最後の Block が禍し、データはひとつも入って来てはくれません。
不正行 をスキップ では無く、全データ無し、 です。

typeof(string) に変更するか、
<Year>0</Year> に変更するか、
で、 正常に動きました!。

気付いた 切っ掛け は、
dt.ReadXml(reader); を、
XmlReadMode m = dt.ReadXml(reader); に変え、
Debug すると、 m には IgnoreSchema (=2) が返っていた事。
Default は Auto (=0) の筈なのに。
そう、 ReadXml は 戻り値 を採るのでした。

勿論、試行覚悟の段階で、
dt.Columns.Add(new DataColumn("RegID", typeof(string))); 等の定義を外すと、
Xmlからのスキーマ推論をサポートしない と怒られます。


参考迄に、 我が 人生最初の C# Coding から 抜粋して 記載して置きますね。


    public partial class Form1 : Form
    {
        private BindingSource bs = new BindingSource();

        public Form1()
        // 中略 //

        private void GetRegData()
        {
            string exeAbsolutepath = AppDomain.CurrentDomain.BaseDirectory;   // EndWith "¥"
            string xmlRelativePath = "Dictionaries" + Path.DirectorySeparatorChar;
            string xmlDefault = "SomeList.xml";
            string fn = exeAbsolutepath + xmlRelativePath + xmlDefault;
            DataSet ds = new DataSet();
            DataTable dt = new DataTable("Items");
            dt.Columns.Add(new DataColumn("RegID", typeof(string)));
            dt.Columns.Add(new DataColumn("RegFile", typeof(string)));
            dt.Columns.Add(new DataColumn("RegTitleJp", typeof(string)));
            dt.Columns.Add(new DataColumn("RegYear", typeof(int)));
            using (StreamReader reader = new StreamReader(fn))
            {
                dt.ReadXml(reader);
            }
            bs.DataSource = dt;
            this.dataGridView1.DataSource = bs;
        }


因みに、.xml の雛形はこんな感じ。
無論、Linux での運用も考慮し、UTF-8 & LF で作成しています。
   CR+LF でも、行ける のかも知れませんが、念の為。


<?xml version="1.0" encoding="utf-8"?>
<Table1>

<Items>
<RegID>0001001</RegID>
<RegFile>007_Royale</RegFile>
<RegTitleJp>007 ロワイヤル</RegTitleJp>
<RegYear>2006</RegYear>
</Items>

<!-- 中略 -->

<Items>
<RegID></RegID>
<RegFile></RegFile>
<RegTitleJp></RegTitleJp>
<RegYear>0</RegYear>
</Items>

</Table1>


尚、
xml データ作成時の 単純なミス(例:Tag '<'/'>' 欠落等 )は、
Visual Studio IDE 上で、ファイルを選択すると、
狂ってるよ! と Error 表示で注意喚起してくれます。
其処から、クリックで、該当箇所に Jump !。
ファイルは結構な行数になるので、 ありがたい。  ;)



0 件のコメント:

コメントを投稿