|
|
第2回 処理対象を選択する基本構文
前回は,LINQ to XMLの概要について説明した。今回から,実際にLINQクエリーのサンプル・コードを取り上げて解説していく。 XMLデータ処理で避けて通れないのは,処理対象ノードの選択である。W3C仕様でいえば,XPathのロケーションパスの指定方法にあたるものだ。ロケーションパスが,DOM,XSLT,XQueryの中で用いられていることを考えれば,その必要性は自明である。
XML文書の読み込みまず,処理対象とするXML文書が必要なので,既存のXMLファイルを読み込んでおこう。作成したASP.NETプロジェクトの,ソリューションエクスプローラから,App_Dataフォルダ内に,リスト1のXMLファイル(udons_sampleData.xml)を追加する。文字コードはUTF-8だ。本稿で使用するXMLファイルはすべて,App_Dataフォルダ内に読み込んでおく必要がある。
1.XDocumentとXElement最初に,XDocumentやXElementクラスのLoadメソッドを使い,XMLファイル名を指定して読み込む。それから,読み込んだ文書のルートノードを起点として,任意の要素や属性といった選択対象までの道のりを,パスで指定していく。 その際,LINQ to XML軸の起点となるルートノードの扱い方が,XPathとは異なるので注意する必要がある(XSLTに詳しい人は,XSLTのdocument関数での参照先指定をイメージしてほしい)。System.Xml.Linq名前空間には,XDocumentとXElementという二つのクラスがあり,この二つのどちらを使うか,つまり「どのようにしてXML文書を読み込むか」によって,起点が異なるのである。 XDocumentクラスは,その名の通り,XMLドキュメントを表す。XDocument.Loadで読み込んだ場合は,読み込んだXML文書のルート要素ノードは「ルートノードの子扱いになる」。ルートノードの子孫といえば,読み込んだXML文書のルート要素以下を指す。 一方,XElementクラスは,XML要素を表す。XElement.Loadで読み込んだ場合は,読み込んだXML文書のルート要素ノードが「ルートノード扱いになる」。ルートノードの子孫とは,読み込んだXML文書のルート要素の子孫を指す。つまり,ルート要素自身は含まれない。 起点が異なると,クエリーの記述方法も異なる。XMLデータの処理ではルート要素の子孫を処理するケースが多いので,XElementクラスを使うのが基本である。本稿でも基本的にXElement.Loadで読み込んでいる。 XML文書(ファイル)を読み込む構文は,次の通りだ。
Dim returnValue As XDocument= XDocument.Load(XMLファイルのURI)
先のリスト1を,それぞれの方法で読み込むと,結果は図1のようになる。上図がXDocument.Loadで読み込んで子要素のコレクションを取得した場合,下図がXElement.Loadで読み込んで子要素のコレクションを取得した場合だ。
このように,XDocumentクラスを使った場合,ルートノードの子要素のコレクションとは,ルート要素である<商品情報>以下になる。 一方,XElementクラスを使った場合は,ルート要素<商品情報>がルート扱いになるので,子要素のコレクションとは<商品>要素以下となる。 LINQクエリーのコードは,リスト2のように記述する。
(1)ImportsメソッドでSystem.LinqとSystem.Xml.Linq名前空間を読み込む。System.Linq名前空間は,LINQを使用するクエリーをサポートするクラスとインターフェイスを提供する。System.Xml.Linq名前空間は,LINQ to XMLでXMLを処理するクラスが含まれている。 (2)Server.MapPathでサーバー上の物理パスを指定する。 (3)次にApp_Dataフォルダ内に読み込んでおいた,udons_sampleData.xmlを読み込む。ここでは,XDocumentクラスのLoadメソッドを使用している。 (4)IEnumerable (Of T)ジェネリック・インタフェースを使い,指定した型のコレクションに対する単純な反復処理を実行する。構文は,次の通りだ。 IEnumerable(Of 列挙するオブジェクトの型)
xmldoc.Elementsクエリーで,読み込んだXML文書の要素を選択している。Elementsメソッドは,ドキュメントの子要素のコレクションをドキュメント順に返す。ここでは,XDocumentクラスで読み込んだXMLの要素に対してクエリーを発行しているので,ルート要素(<商品情報>)が含まれて選択される。なお,Elements(要素名)と記述した場合は,指定した要素のコレクションをドキュメント順に返す。この場合はXElement.LoadでXMLを読み込む。 (5)クエリーを作成しただけでは,クエリーは実行されない。クエリー変数queryDoc内にクエリーの定義が格納されるだけだ。そこで,For Each〜Inステートメントを使用してクエリーを実行し,TextBox1コントロール内にXML文書を表示している。このような処理を「遅延実行」という。構文は,次の通りだ。
「遅延実行」以外に,クエリーを定義するのと同時に実行される「即時実行」がある。これは,単一の値を返す標準クエリー演算子の使用によって強制的に行われる。詳しくは第4回で取り上げる。 XSLTユーザーなら,For Each〜Inステートメントは,<xsl:for each select=”処理対象ノード”></xsl:for-each>をイメージすればわかりやすいだろう。 (6)TextBox2内に表示されるXML文書は,XElement.Loadメソッドで読み込んでいるため,ルート要素(<商品情報>)の子である<商品>要素以下となる。
>>2.リテラル・データとしての読み込み
連載新着連載目次へ >>
|