連載
» 2003年06月25日 10時00分 公開

XMLテクニック集(2):XML文書からソーティングされた一覧表を作成する (1/3)

[山田祥寛,@IT]

XML文書からソーティングされた一覧表を作成する

アイコン

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 version="1.0" encoding="Shift_JIS" ?>
<?xml-stylesheet type="text/xsl" href="table.xsl" ?>
<books xml:space="default">
  <book>
    <title>10日でおぼえるJSP/サーブレット入門教室</title>
    <author>Y.Yamada</author>
    <published>翔泳社</published>
    <price>2800</price>
    <publishDate>2002/05/17</publishDate>
  </book>
  <book>
    <title>JSP/PHP/ASPサーバサイドプログラミング徹底比較</title>
    <author>Y.Yamada</author>
    <published>技術評論社</published>
    <price>2880</price>
    <publishDate>2002/12/16</publishDate>
  </book>
  <book isbn="ISBN4-7980-0522-3">
     <title>プチリファレンスJSP&サーブレット</title>
    <author>Yamada Yoshihiro</author>
    <published>秀和システム</published>
    <price>1800</price>
    <publishDate>2003/04/15</publishDate>
  </book>
  <book isbn="none">
    <title>基礎から学ぶサーブレット/JSP</title>
    <author>Yamada Yoshihiro</author>
    <published>@IT</published>
    <price>0</price>
    <publishDate>2003/01/09</publishDate>
  </book>
  <book isbn="ISBN4-7980-0478-2">
    <title>今日からつかえるJSP&サーブレットサンプル集(応用編)</title>
    <author>山田祥寛</author>
    <published>秀和システム</published>
    <price>3200</price>
    <publishDate>2003/03/08</publishDate>
  </book>
</books>


 このような「繰り返し型」のXML文書を処理するのが、XSLT要素の1つ<xsl:for-each>要素の役割です。具体的な例を見てみましょう。なお、XML文書とXSLTスタイルシートを静的に関連付ける方法については、「XML文書にXSLTスタイルシートを静的にひも付ける」を参照してください。

[table.xsl]

<?xml version="1.0" encoding="Shift_JIS" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:template match="/">
    <html>
      <head>
(2)     <title><xsl:value-of select="books/@name" /></title>
      </head>
      <body>
        <h1><xsl:value-of select="books/@name" /></h1>
        <table border="1">
          <tr>
            <th>ISBNコード</th><th>書名</th><th>著者</th>
            <th>出版社</th><th>価格</th><th>発刊日</th>
          </tr>
(1)       <xsl:for-each select="books/book">
(3)         <xsl:sort select="published" data-type="text" order="descending" />
(4)         <xsl:sort select="price" data-type="number" order="ascending" />
            <tr>
(2)              <td nowrap="nowrap"><xsl:value-of select="@isbn" /></td>
              <td nowrap="nowrap"><xsl:value-of select="title" /></td>
              <td nowrap="nowrap"><xsl:value-of select="author" /></td>
              <td nowrap="nowrap"><xsl:value-of select="published" /></td>
              <td nowrap="nowrap"><xsl:value-of select="price" /></td>
              <td nowrap="nowrap"><xsl:value-of select="publishDate" /></td>
            </tr>
(1)       </xsl:for-each>
        </table>
      </body>
    </html>
  </xsl:template>
</xsl:stylesheet>



 上記のXSLTスタイルシートをbook.xslに適用すると、下記のような画面を表示するHTML文書が作成されます。

XML文書がソートされ、一覧表に整形される XML文書がソートされ、一覧表に整形される

 それでは、以下にXSLTスタイルシートtable.xslで注目すべきポイントについてまとめておくことにしましょう。

(1)<xsl:for-each>要素は繰り返す

 <xsl:for-each>要素は、select属性で指定された式にマッチングした「ノード集合」すべてについて、繰り返し処理を行います。

 上の例の場合は、<books>要素配下のすべての<book>要素について、順番に処理を行っていきます。ループの1周ごとに1つの<book>要素が処理され、HTMLテーブルの1行(<tr>〜</tr>)として出力されます。つまり、<xsl:for-each>要素による処理(ループ)が終了したとき、<book>要素の数である5行のテーブル行が出力されているイメージです。

(2)カレントノードという概念

 <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属性で指定されたノードからの相対的な位置を記述しなければなりません。

(3)出力順序を制御する

 <xsl:sort>要素を使用することで、表の出力順序(ソート順序)を指定することができます。

 例えば以下のように指定した場合、<book>要素配下の<published>要素を第1キーに、<price>要素を第2キーに表を出力します。<xsl:sort>要素を記述する順番がそのまま、ソートキーの優先順となる点に注意してください。

<xsl:sort select="published" data-type="text" order="descending" />
<xsl:sort select="price" data-type="number" order="ascending" />


 data-type属性はソート対象データの型(text|number)を、order属性はソート順(ascending:昇順[デフォルト]、descending:降順)を、それぞれ指定します。

 特に、データが数値であるにもかかわらず、data-type属性をtextと指定してしまった場合には、正しくソート処理が行われない場合がありますので、注意してください。これを誤ってしまうと、例えば“500”と“90”を文字列として比較した場合には、“5”と“9”とを比較して“90”の方が大きいことになってしまいます。

       1|2|3 次のページへ

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。