|
LINQ to XMLの基礎編は,今回が最終回だ。これまでの4回で,処理対象の選択,クエリーの取得,XMLツリーの生成や変更,演算子,関数と見てきた。最後に,ソートや検索,データの結合について解説する。
これで最低限必要なコードは一通り網羅することになる。XML文書の扱いに慣れていない人は戸惑ったかもしれないが,自分で2~3回書いてデバッグしてみれば,コツがつかめてくるだろう。
今回の開発に使った筆者の環境は,Visual Studio Team System 2008である。本稿で取り上げるのはASP.NETプログラムで,開発言語はVisual Basic。ASP.NETでLINQを試すなら,無料で公開されているVisual Web Developer 2008 Express Editionが,マイクロソフトのWebサイトからダウンロードできる。 なお,本記事で紹介するサンプル・プログラムのソース・ファイル(zipアーカイブ)は,下記からダウンロードできる。 |
ソート
本連載第3回の「インメモリーのオブジェクトからXMLを生成する処理(リスト19)」で少し触れたが,LINQクエリーの結果はソートすることができる。構文は次の通りだ。
■昇順
Dim query As IEnumerable(Of XElement) = From 範囲変数(反復変数) In 対象コレクション Order By クエリー結果に含まれる一つ以上の要素 Ascending(デフォルトで省略可)
■降順
Dim query As IEnumerable(Of XElement) = From 範囲変数(反復変数) In 対象コレクション Order By クエリー結果に含まれる一つ以上の要素 Descending
ソートして件数を表示
ここでは,リスト1のようなXML文書のデータを,図1のように<価格>の降順にソートし,さらに,データ件数を取得して表示してみよう。
<?xml version="1.0"?>
<商品情報>
<商品 品番="udon_01">
<品名>天ぷらうどん</品名>
<セット内容>うどん、かけつゆ、えび天ぷら、あげ巻き</セット内容>
<価格>3500</価格>
</商品>
<商品 品番="udon_02">
<品名>かきあげうどん</品名>
<セット内容>うどん、かけつゆ、季節のかきあげ、かまぼこ</セット内容>
<価格>2800</価格>
</商品>
<商品>~</商品>繰り返し,略
</商品情報>
| |
図1●<価格>の降順にソートし,データ件数を取得/表示している [画像のクリックで拡大表示] |
処理のコードはリスト2の通りである。
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim filePath As String = Server.MapPath("./")
Dim xmldoc As XElement = XElement.Load(filePath & "App_Data/udons_2008_hinban_attribute.xml")
Dim query As IEnumerable(Of XElement) = From c In xmldoc.Elements("商品") Order By Integer.Parse(c.<価格>.Value) Descending
Label1.Text = query.Count & "件のデータ"
For Each result In query
TextBox1.Text &= result.ToString & vbCrLf
Next
End Sub
Order By句に,Integer.Parseメソッドで数値に変換した<価格>要素の値(c.<価格>.Value)を指定し,その値をDescending(降順)でソートしている。範囲変数cは<商品>要素のコレクションを参照している。
部分一致検索
今度は,実務で用途の多い検索処理について見ていこう。まず,指定した文字列をデータとして含む要素を抽出してみよう。
1.指定文字列を含む特定要素の抽出
XPathやXQueryに,contains関数が用意されているように,LINQでは,Containsメソッドが用意されている。このメソッドを使うと,指定した文字列が含まれていればTrue,含まれていなければFalseが返される。構文は次の通りだ。
String.Contains(Stringに含まれる文字列)
リスト1のXML文書から,<セット内容>要素に「かまぼこ」が含まれる<商品>を抽出するには,リスト3のように記述する。
Where句以降に,Containsメソッドを使って,<セット内容>要素内に「かまぼこ」の含まれるすべての<商品>要素を取り出す条件を記述している。結果は図2の通りだ。
Dim query As IEnumerable(Of XElement) = From c In xmldoc.Elements("商品") Where c.<セット内容>.Value.Contains("かまぼこ") Select c
For Each result In query
TextBox1.Text &= result.ToString & vbCrLf
Next
| |
図2●<セット内容>に「かまぼこ」が含まれる<商品>を検索した結果 [画像のクリックで拡大表示] |