車の情報まとめアプリ02(ドロップダウンリストへのxmlバインディング2)

■前回に引き続きドロップダウンリストへのxmlバインディングの検討。
ドロップダウンリストからXmlDataSourceを指定することでデータバインディングしようとしたけど、xmlファイルの中にidなどを入れていない状態では、Visual Studio 2019のプロパティ(DataTextFieldなど)から参照先がでなかった。実行はできるけど、ドロップダウンリストに入るデータは、System.Web.Ul.WebControls.XmlDataSourceNodeDescriptor という(おそらく)クラス名が直接でているよう。

調べてみたけどプロパティで設定する方法が見つからない。xmlファイルを読み込んでその要素を取り出す方法はいくらでもありそうなので、コード上(aspxファイルでなくaspx.vbファイル)で要素を取得し、それをドロップダウンリストに追加する方法を試してみた。

コードは下の通り。これをPage_Loadメソッド内において、プログラムの実行時に動作するようにした。

 Dim xdoc = XDocument.Load("xmlファイルのフルパス指定")
 Dim list As IEnumerable(Of XElement) = System.Xml.XPath.Extensions.XPathSelectElements(xdoc, "./VehicleInfoList/Vehicle/Brand")
        For Each el As XElement In list
            Debug.WriteLine(el.Value)
            If (DropDownList1.Items.Contains(New ListItem(el.Value))) Then
            Else
                DropDownList1.Items.Add(el.Value)
            End If
        Next
        DropDownList1.DataBind()

ここでは、Loadしたxmlファイルから、XPathSelectElementsメソッドでXPath「./VehicleInfoList/Vehicle/Brand」の先にある要素をリストとして取得し、For文で違う内容の要素だけをドロップダウンリストに入れている。参照するxmlファイルは下のようなもので、Brand部分に車両メーカーが入っている。車両ごとにデータ入力しているので、当然同じメーカーが入る場合もある。

実行結果が下のもの。意図する通り、車両メーカーは一つずつしかドロップダウンリストには入っていない。

コード部分で処理すればいろいろできるだろうけど、この場合、そもそもXmlDataSourceを入れる必要もなくなる。ドロップダウンリストのプロパティ部分の設定で、idなどが設定されていないxmlファイルの要素の中身を取りだす方法もありそうな気がするけど、別のデータリストか何かを一度間に入れたりすればいいのかな。

ちなみに、Repeaterクラスでは、XmlDataSourceで指定したファイルからXPathを指定して要素を埋め込むといったことができた。

下では、XmlDataSource2のXPathプロパティで「VehicleInfoList/Vehicle」まで指定しているので、その先のXPathをReapterクラス内で設定。

            <asp:Repeater ID="Repeater1" runat="server" DataSourceID="XmlDataSource2">
            <ItemTemplate>
                <p><%# XPath("./Brand") %></p>
                <p><%# XPath("./VehicleName") %></p>
            </ItemTemplate>
            </asp:Repeater>

<p>タグ(パラグラフ)として、メーカー名と車両名が繰り返し表示されている。ここまではaspx.vbファイルの操作は行っていない。