条件に応じて処理を変える
■条件が単一の場合
要素名や属性値に応じて、スタイルシートの中で適用するテンプレートを使い分けたいときがあります。こうした条件付き処理のため、XSLTではxsl:if要素が用意されています。
<xsl:if test="式">
テンプレート
</xsl:if> |
xsl:ifは、test属性の式の値が真の場合、テンプレートに書かれた要素や属性を生成します。なお、いくつかのプログラミング言語にはif文の対となるelse文がありますが、XSLTにはxsl:elseなるものはありません。
例を使って条件付き処理の仕方を示しましょう。以下のリストは、書籍名一覧のXMLデータですが、書籍のジャンルを示すgenre属性が付加されています(リストの2行目の<?xml:stylesheet …?>で、適用するXSLTスタイルシートを指定しています。スタイルシートの指定については、第1回「XSLTスタイルシートの基礎の基礎」を参照してください)。
<?xml version="1.0" encoding="shift_jis"?>
<?xml:stylesheet type="text/xsl" href="condition.xsl"?>
<books>
<title genre="travel">東北地方ガイドブック</title>
<title genre="computer">標準XML 完全解説
改訂版</title>
<title genre="ecology">オゾン層破壊と紫外線</title>
<title genre="hobby">入門デジタルカメラ撮影術</title>
</books> |
上のリストの、genre属性を手がかりにコンピュータ関連の本だけを選択してIE 5に表示させたいとします。このためのXSLTスタイルシート(condition.xsl)は次のとおりです。
<?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:apply-templates/>
</ul>
</xsl:template>
<xsl:template match="title">
<xsl:if test="@genre='computer'">
<li><xsl:value-of select="."/></li>
</xsl:if>
</xsl:template>
</xsl:stylesheet> |
上のスタイルシートは、XSLT処理の出発点であるルートノード(“/”)から始めて、books要素、title要素の順にテンプレートルール(すなわちxsl:template要素)を適用しています。xsl:if要素の部分を抜き出して詳しく見てみましょう。
<xsl:if test="@genre='computer'"> |
@genreは、カレントノード(ここではtitle要素)のgenre属性を指しています。このxsl:if要素は、「genre 属性の値が'computer 'となる場合、xsl:if要素内のテンプレートを処理しなさい」という意味です(computerという文字列が、二重引用符(")ではなく単引用符(')で囲まれていることに注意してください)。
与えられたXMLデータの中でgenre属性が'computer'の書籍は、「標準XML完全解説改訂版」だけですので、以下のリストと等価のHTMLデータが生成されます。
<html>
<body>
<h3>コンピューター関連書籍</h3>
<ul>
<li>標準XML 完全解説 改訂版</li>
</ul>
</body>
</html> |
従って、IE 5による表示結果は下図のようになります。
XMLデータの中から、コンピューター関連書籍のみをスタイルシートで抜き出して表示させた
■複数の条件から選択する場合
複数の条件を選択して処理するために、choose-case文が用意されているプログラミング言語があります。XSLTでは、それに相当するものとしてxsl:choose要素が使われます。
<xsl:choose>
<xsl:when test="式">
テンプレート
</xsl:when>
……
xsl:when 要素の繰り返し
……
<xsl:otherwise>
テンプレート
</xsl:otherwise>
</xsl:choose> |
xsl:when要素は、xsl:choose要素にとって必須の要素なので少なくとも1つは存在しなければなりません。XSLTプロセッサは、xsl:whenを順番に評価してゆき、xsl:whenのtest 属性の値が真となる最初のxsl:when要素のテンプレートだけを処理します。その後に続くxsl:when要素についてはtest 属性が真かどうかは評価されません。
該当するxsl:when要素が1つもない場合、xsl:choose要素の最後の子要素となるxsl:otherwise要素のテンプレートが処理されます。ただし、xsl:whenとは異なりxsl:otherwise はxsl:chooseにとって任意指定の要素なので、xsl:otherwiseがなくても構いません。その場合、XSLTプロセッサは何も生成しません。
先ほどと同じXMLデータでxsl:choose要素の使い方を例示します。genre属性を手がかりにして分類項目を付けた書籍名一覧表をIE5 で表示させる例です。適用するスタイルシートを以下に示します。
<?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">
<table border="3">
<tr>
<th>分類</th>
<th>書籍名</th>
</tr>
<xsl:apply-templates/>
</table>
</xsl:template>
<xsl:template match="title">
<tr>
<xsl:choose>
<xsl:when test="@genre='computer'">
<td>コンピュータ</td>
<td><xsl:value-of
select="."/></td>
</xsl:when>
<xsl:when test="@genre='travel'">
<td>旅行</td>
<td><xsl:value-of
select="."/></td>
</xsl:when>
<xsl:when test="@genre='hobby'">
<td>趣味</td>
<td><xsl:value-of
select="."/></td>
</xsl:when>
<xsl:otherwise>
<td>その他</td>
<td><xsl:value-of
select="."/></td>
</xsl:otherwise>
</xsl:choose>
</tr>
</xsl:template>
</xsl:stylesheet> |
genre属性が'computer'、'travel'、'hobby'である場合、およびそのほかの場合に、処理が選択できるようになっています。処理結果は下記のHTMLデータと等価のものが生成されます。
<html>
<body>
<table border="3">
<tr>
<th>分類</th>
<th>書籍名</th>
</tr>
<tr>
<td>旅行</td>
<td>東北地方ガイドブック</td>
</tr>
<tr>
<td>コンピュータ</td>
<td>標準XML 完全解説
改訂版</td>
</tr>
<tr>
<td>その他</td>
<td>オゾン層破壊と紫外線</td>
</tr>
<tr>
<td>趣味</td>
<td>入門デジタルカメラ撮影術</td>
</tr>
</table>
</body>
</html> |
IE 5による表示結果は下図のようになります。
IE5による表示結果。XMLデータがスタイルシートによってHTMLデータに変換され、表示されている
■同じ処理を繰り返す
プログラミングに必須の機能の1つに繰り返し処理があります。XSLTではxsl:for-each要素を使って繰り返し処理を行います。xsl:for-each要素は、select属性で指定されたノードについてテンプレートを繰り返し適用します。
<xsl:for-each select = ノード集合を返す式
>
……
処理が繰り返されるテンプレート
……
</xsl:for-each> |
前節と同じXMLデータを使って説明しましょう。ただし、簡略のためgenre属性を省いています。
<?xml version="1.0" encoding="shift_jis"?>
<?xml:stylesheet type="text/xsl " href="iteration.xsl"?>
<books>
<title>東北地方ガイドブック</title>
<title>標準XML 完全解説 改訂版</title>
<title>オゾン層破壊と紫外線</title>
<title>入門デジタルカメラ撮影術</title>
</books> |
このXMLデータに以下のスタイルシート(iteration.xsl)を適用します。xsl:for-each要素によってbooks要素の子であるすべてのtitle要素について処理が繰り返されることになります。
<?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">
<li><xsl:value-of
select="."/></li>
</xsl:for-each>
</ul>
</xsl:template>
</xsl:stylesheet> |
結果として以下のHTMLデータが生成され、ブラウザで表示できるようになりました。
<html>
<body>
<h3>繰り返し処理による書籍名一覧</h3>
<ul>
<li>東北地方ガイドブック</li>
<li>標準XML 完全解説 改訂版</li>
<li>オゾン層破壊と紫外線</li>
<li>入門デジタルカメラ撮影術</li>
</ul>
</body>
</html> |
IE 5による表示結果を以下に示します。
IE5による表示結果。XMLデータがスタイルシートによってHTMLデータに変換され、表示されている
条件判断や繰り返しが使えるようになると、スタイルシートでできることがずっと広がるようになります。次回はソートや変数などを紹介していきましょう。
次回は来週9月18日に掲載予定です。
本記事は、日本ユニテック発行のXMLテクノロジー総合情報誌「Digital Xpress」に掲載された、XSLT特集「XSLTの実力を探る!」第1回から第3回の内容をもとに、加筆修正したものです。