XSLTによるデータのソートと変数とパラメータXSLTスタイルシート書き方講座(4)

XSLTスタイルシートのプログラミングに、ソートや変数が使えるようになれば、ビジネスでの応用範囲がぐっと広がります。XSLTスタイルシートの書き方講座、最後の仕上げはこれらの使い方について解説しましょう。

» 2001年09月18日 00時00分 公開
[奥井康弘, 吉田稔株式会社日本ユニテック]

与えられたXMLデータのソート処理

 ある条件に従ってデータを抽出した後、それらをソート処理することもプログラミングによくあるケースです。ここでは、xsl:for-each要素のselect属性で選択したノードをソートしてから結果のXMLデータを出力する方法を説明しましょう。

 XSLTには、ソート処理のためにxsl:sort要素が用意されています。xsl:sort要素の属性指定について以下にまとめました。xsl:sort要素にどんな機能が盛り込まれているのかよく見てください。

<xsl:sort
    select = "ソートキーとなる文字列を返す式"
    lang = {"ソートキーの言語"}
    data-type = {"text"|"number"|"名前空間接頭辞付きの修飾名" }
    order = {"ascending"|"descending" }
    case-order = {"upper-first"|"lower-first" } />

data-type属性 文字列のデータ型を指定する。
order属性 ソートを昇順、降順のどちらで行うかを指定する。デフォルトは"ascending"。
case-order属性 data-typeが"text"のとき、大文字と小文字のどちらを優先させるかを指定する。

 例を挙げて使い方を見てみましょう。次のXMLデータをソートします。

<?xml version="1.0" encoding="shift_jis"?>
<?xml:stylesheet type="text/xsl" href="sort.xsl"?>
<books>
  <title price="1500">東北地方ガイドブック</title>
  <title price="2280">標準XML 完全解説 改訂版</title>
  <title price="2000">オゾン層破壊と紫外線</title>
  <title price="1800">入門デジタルカメラ撮影術</title>
</books>

 title要素のprice属性を手がかりに、価格順にソートするには、以下のスタイルシート(sort.xsl)を書きます。このスタイルシートでは、xsl:for-eachの対象として選択したtitle要素のノード集合を、price属性でソートした後にテンプレートの内容を適用しています。

<?xml version="1.0" encoding="shift_jis"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/">
    <html>
      <body>
        <xsl:apply-templates/>
      </body>
    </html>
  </xsl:template>
  <xsl:template match="books">
    <h3>価格順の書籍名一覧</h3>
    <ul>
      <xsl:for-each select="title">
        <xsl:sort select="./@price" data-type="number" order="ascending"/>
        <li><xsl:value-of select="."/>(税別<xsl:value-of select="./@price"/>円)</li>
      </xsl:for-each>
    </ul>
  </xsl:template>
</xsl:stylesheet>

 結果として、以下のHTMLデータが得られます。

<html>
  <body>
    <h3>繰り返し処理による書籍名一覧</h3>
    <ul>
      <li>東北地方ガイドブック(税別1500円)</li>
      <li>入門デジタルカメラ撮影術(税別1800円)</li>
      <li>オゾン層破壊と紫外線(税別2000円)</li>
      <li>標準XML 完全解説 改訂版(税別2280円)</li>
    </ul>
  </body>
</html>

 IE 5による表示結果を以下に示します。

price属性でソートされたため、価格順に結果が表示された price属性でソートされたため、価格順に結果が表示された

 xsl:sort要素は、xsl:for-eachだけでなくxsl:apply-templatesの子要素として使用することもできます。その場合は、xsl:apply-templates によって選択されたノード集合をソートしてから、その順番でノードに対するテンプレートを適用することになります(通常は、XMLデータをツリーに見立てて、たどる順番で処理されます)。

変数とパラメータ

 XSLTでは、変数も使用することができます。変数への値の割り当てには、次の2つのXSLT 要素を使うことができます。

xsl:param スタイルシートあるいはテンプレートを呼び出すときに、パラメータとして渡すことができる変数を決め、そのデフォルト値を割り当てる。
xsl:variable スタイルシート全体あるいは、テンプレート内で使用する値を変数に割り当てる。

 xsl:paramは、スタイルシートあるいはテンプレートを呼び出すときに、パラメータとして渡すことができる変数を決め、そのデフォルト値を割り当てる命令です。一方、xsl:variableは、スタイルシート全体あるいは、テンプレート内で使用する値を変数に割り当てるものであり、パラメータ渡しのような機能はありません。

変数への値の割り当て

 変数への値の割り当てにはselect属性を使うことができます。以下のように書くことによって、変数xに0.05という数値が割り当てられます。

<xsl:param name="x" select="0.05" />
<xsl:variable name="x" select="0.05" />

 select属性を使って値を割り当てる方法のほかに、xsl:param要素あるいはxsl:variable要素の内容としてテンプレートを書き、そのテンプレートに従って生成されるノード集合を変数に割り当てる方法もあります。

<xsl:variable name="header">
  <h1>変数の割り当て方</h1>
  <h2>select属性を使う場合と使わない場合</h2>
<xsl:variable/>

 この場合、変数headerに割り当てられるノード集合とは、以下に図示するとおり、一時的なルートノードに、h1要素とh2要素が子テキストノードとともにぶら下がっているツリーになります。

変数headerに割り当てられるノード集合 変数headerに割り当てられるノード集合

 従って、次のように書くと、変数xには数値0.05ではなく、一時的なルートノードの下に“0.05”という文字列値を持つテキストノードがぶら下がっているノード集合が割り当てられます。

<xsl:variable name="x">0.05<xsl:variable/>

変数xに割り当てられるノード集合 変数xに割り当てられるノード集合

 変数xに数値が割り当てられていると勘違いしてスタイルシートを書くと、思いどおりの結果にならないことがありますので注意してください(詳細はXSLTの仕様書を見てください)。変数xに数値を割り当てたいのなら、次のように書くべきでしょう。

<xsl:variable name="x" select="0.05"/>

xsl:variableの使い方

 例を用いてxsl:variable要素の使い方を示します。次のスタイルシートを見てください。消費税率を変数で表して、商品の税込価格を計算します。なお、スタイルシートの中で変数の値を参照するときは、変数名の前に“$”を付けた書式で記述します。例えば、変数taxの値を参照するときは、“$tax”と記述します。

<?xml version="1.0" encoding="shift_jis" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:variable name="tax" select="0.05"/>
  <xsl:template match="/">
    <html>
      <body>
        <xsl:apply-templates/>
      </body>
    </html>
  </xsl:template>
  <xsl:template match="books">
    <table border="1">
    <tr><th>書籍名</th><th>税込価格</th></tr>
    <xsl:apply-templates/>
    </table>
  </xsl:template>
  <xsl:template match="title">
    <tr>
      <td><xsl:value-of select="."/></td>
      <td><xsl:value-of select="./@price *(1+$tax)"/></td>
    </tr>
  </xsl:template>
</xsl:stylesheet>

 これを以下のようなXMLデータに適用すると、税込みの価格が表形式で表示されます(このサンプルでは、IE 5で表示するためにスタイルシートにvariable.xslという名前を付けています)。

<?xml version="1.0" encoding="shift_jis"?>
<?xml:stylesheet type="text/xsl" href="variable.xsl"?>
<books>
  <title price="1500">東北地方旅行ガイド</title>
  <title price="1800">入門デジタルカメラ撮影術</title>
</books>

 結果として生成されるHTMLデータを以下に示します。税込み価格が計算され、埋め込まれているのがお分かりだと思います。

<html>
  <body>
    <table border="3">
      <tr>
        <th>書籍名</th>
        <th>税込価格</th>
      </tr>
      <tr>
        <td>東北地方ガイドブック</td>
        <td>1575</td>
      </tr>
      <tr>
        <td>入門デジタルカメラ撮影術</td>
        <td>1890</td>
      </tr>
    </table>
  </body>
</html>

 IE 5の表示を下記に示します。

変数をもとにして計算された税込価格が表示された 変数をもとにして計算された税込価格が表示された

xsl:paramの使い方

 xsl:param要素で指定されるパラメータの値はデフォルト値であり、スタイルシートやテンプレートの呼び出し時に値が指定されると、デフォルト値からその値に置き換えることができます。テンプレートを呼び出したときに、値をxsl:with-paramで渡すことができます。次のリストに示すとおりです。なお、変数と同様、スタイルシートの中でパラメータの値を参照するときは、パラメータ名の前に“$”を付けた書式で記述します。例えば、パラメータtaxの値を参照するときには、“$tax”と記述します。

<?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>
      <body>
        <xsl:apply-templates/>
      </body>
    </html>
  </xsl:template>
  <xsl:template match="books">
    <table border="1">
      <tr><th>書籍名</th><th>税込価格</th></tr>
      <xsl:apply-templates>
        <xsl:with-param name="tax" select="0.05"/> ←tax変数の値を指定
      </xsl:apply-templates>
    </table>
  </xsl:template>
  <xsl:template match="title">
    <xsl:param name="tax" select="0.03"/> ←このtax変数の値は、後で0.05 に置き換わる
    <tr>
      <td><xsl:value-of select="."/></td>
      <td><xsl:value-of select="./@price *(1+$tax)"/></td>
    </tr>
  </xsl:template>
</xsl:stylesheet>

 テンプレートの中でtax に割り当てた値はデフォルトであり、パラメータが渡されると、その値に置き換わります。

スタイルシートへのパラメータ渡し

 先ほどの例では、スタイルシート内でテンプレートに対するパラメータの値を決めましたが、パラメータをスタイルシートの外部から与えたいこともあります。そのようなときには、xsl:param要素をxsl:stylesheetの直下に置きます。

<xsl:stylesheet xmlns:xsl=http://www.w3.org/1999/XSL/Transform version="1.0">
……
<xsl:param name="tax">0.05</xsl:param>
……

 ただし、ブラウザから参照するだけでは、スタイルシートにパラメータを与えることはできません。通常は、XSLTプロセッサをコマンドラインから呼び出すとき、またはXSLTプロセッサをプログラムから呼び出すときにパラメータを与えることになりますが、その呼び出し方はツールごとに異なります。それぞれのツールの解説書を覧ください。

まとめ

 本稿で入門レベルのXSLTの機能を解説しました。XSLT/XPathにはほかにも便利な関数や命令が数多く用意されていて、さらに高度な処理ができるようになっています。また時期をあらためて、本連載の続編であるXSLTの応用編を@ITに掲載する予定です。さらにXSLTを詳しく学びたいという方は、期待してお待ちください。

本記事は、日本ユニテック発行のXMLテクノロジー総合情報誌「Digital Xpress」に掲載された、XSLT特集「XSLTの実力を探る!」第1回から第3回の内容をもとに、加筆修正したものです。



Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

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

メールマガジン登録

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