XML文中に、繰り返し同じ種類のデータが記述されるケースは少なくありません。それらをソートしてHTML文書のテーブル形式に整形するための、XSLTスタイルシートの書き方を紹介しましょう。
カテゴリ | XSLT、.NET | |
関連要素 | <xsl:for-each>、<xsl:sort> | |
関連記事 | XML文書にXSLTスタイルシートを静的にひも付ける | |
XML文書では、リレーショナルデータベースのテーブルのように、あるひとかたまりのデータが繰り返し記述されるケースが少なくありません。例えば、以下のような書籍情報一覧(books.xml)などは好例でしょう。この内容をソートして表の形式に整形するXSLTスタイルシートの書き方を紹介します。
元のデータとなるbooks.xmlは<books>要素をルート要素(第1要素)としたXML文書で、各書籍の情報を<book>要素で表現する、典型的な繰り返し型XML文書です。個々の<book>要素配下には、書籍名を表す<title>要素や著者名を表す<author>要素などが含まれます。
[books.xml]
|
このような「繰り返し型」のXML文書を処理するのが、XSLT要素の1つ<xsl:for-each>要素の役割です。具体的な例を見てみましょう。なお、XML文書とXSLTスタイルシートを静的に関連付ける方法については、「XML文書にXSLTスタイルシートを静的にひも付ける」を参照してください。
[table.xsl] |
上記のXSLTスタイルシートをbook.xslに適用すると、下記のような画面を表示するHTML文書が作成されます。
それでは、以下にXSLTスタイルシートtable.xslで注目すべきポイントについてまとめておくことにしましょう。
<xsl:for-each>要素は、select属性で指定された式にマッチングした「ノード集合」すべてについて、繰り返し処理を行います。
上の例の場合は、<books>要素配下のすべての<book>要素について、順番に処理を行っていきます。ループの1周ごとに1つの<book>要素が処理され、HTMLテーブルの1行(<tr>〜</tr>)として出力されます。つまり、<xsl:for-each>要素による処理(ループ)が終了したとき、<book>要素の数である5行のテーブル行が出力されているイメージです。
<xsl:for-each>、<xsl:value-of>などの要素でselect属性を指定する場合、その基点となる「カレントノード」という概念を知っておくべきです。カレントノード、すなわち、「現在のノード」です。よくフォルダ(ディレクトリ)のパスを指定する際に、相対パスという表記がありますが、同様のイメージと思っておけばよいでしょう。
そのカレントノードが、<xsl:for-each>要素配下では移動する点に注意してください。例えば、<xsl:for-each>要素の外の<xsl:value-of>要素では、以下のように文書全体(/)を基点としてノードの指定を行っています。
<title><xsl:value-of select="books/@name"
/></title> |
しかし、<xsl:for-each>要素配下の<xsl:value-of>要素では、
<td nowrap="nowrap"><xsl:value-of select="@isbn"
/></td> |
のように、<book>要素が基点となっているのがお分かりになるでしょう。
これは<xsl:for-each>要素のselect属性において指定した「books/book」に、「カレントノードが移動しているため」なのです。<xsl:for-each>要素配下のノード指定は、<xsl:for-each>要素のselect属性で指定されたノードからの相対的な位置を記述しなければなりません。
<xsl:sort>要素を使用することで、表の出力順序(ソート順序)を指定することができます。
例えば以下のように指定した場合、<book>要素配下の<published>要素を第1キーに、<price>要素を第2キーに表を出力します。<xsl:sort>要素を記述する順番がそのまま、ソートキーの優先順となる点に注意してください。
<xsl:sort select="published" data-type="text"
order="descending" /> |
data-type属性はソート対象データの型(text|number)を、order属性はソート順(ascending:昇順[デフォルト]、descending:降順)を、それぞれ指定します。
特に、データが数値であるにもかかわらず、data-type属性をtextと指定してしまった場合には、正しくソート処理が行われない場合がありますので、注意してください。これを誤ってしまうと、例えば“500”と“90”を文字列として比較した場合には、“5”と“9”とを比較して“90”の方が大きいことになってしまいます。
Copyright © ITmedia, Inc. All Rights Reserved.