XSLT の諸要素

revised: Nov./16th/2003

XSLT文書の説明

ソース・ツリーであるリスト1と、結果ツリーであるリスト5を見比べながら、XSLT文書であるリスト2の中身を見ていきましょう。

XSLT文書はXMLベースのマークアップ言語として定義されているので、XML宣言で始まる整形式のXML文書である必要があります。

XSLT文書のルート要素はstylesheet要素であり、その属性には表1に挙げるものを指定する。

表7. stylesheet要素に指定する代表的な属性
属性
version現時点では1.0のみ(必須)
exclude-result-prefixes結果ツリーに含めない名前空間
xmlns:接頭辞名前空間URI
xmlnsデフォルト名前空間URI

表1の属性で、必ず指定するのが、version属性と、XSLT自身の名前空間URIを指定するxmlns属性です。リスト2で挙げたXSLT文書では、version="1.0" と、XSLT自身の名前空間である "http://www.w3.org/1999/XSL/Transform" を接頭辞 xsl で定義してあります。

<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

例えば、ソース・ツリーで名前空間 "http://www.hoge.foo.demo/ScehmaDemo" を使っている場合は、XSLT文書でもこの名前空間URIを指定しておく必要があります。この名前空間をデフォルト名前空間にして、結果ツリーにはこの名前空間を含めたくないという場合は、次のように指定します。

<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns="http://www.hoge.foo.demo/ScehmaDemo"
                exclude-result-prefixes="#default">

接頭辞にpreを指定する場合は、名前空間URIの指定に xmlns:pre を使い、exclude-result-prefixes属性の値にpreを指定します。

stylesheet要素の直接の子要素に、リスト2では、出力方法を指定するoutput要素と、変換規則を記述するtemplate要素を記述しました。他にも、リスト6に挙げる要素が記述可能です。これらの要素は、XSLT仕様書ではトップ・レベル要素と呼ばれています。本稿では、全てのトップ・レベル要素を紹介することはできません。詳細は、W3CのXSLT 1.0仕様書を参照してください。

リスト6. XSLT文書のトップレベル要素

<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <!-- 外部XSLT文書のインポート
       本スタイルシートの規則よりも優先する -->
  <xsl:import href="..."/>
  
  <!-- 外部XSLT文書のインクルード
       本スタイルシートの規則の方が優先する -->
  <xsl:include href="..."/>
  <!-- スペース区切りの要素名を指定して、
       当該要素のテキスト・ノードから空白を除去する -->
  <xsl:strip-space elements="..."/>
  
  <!-- デフォルトでは全ての要素名が指定されており、
       当該要素の空白をそのまま維持する -->
  <xsl:preserve-space elements="..."/>
  <!-- method属性に"xml" | "html" | "text"を指定して、
       対応する出力形式を指定する -->
  <xsl:output method="..."/>
  <!-- 関数key()で利用する、ノードを参照するキーとその値を定義する -->
  <xsl:key name="..." match="..." use="..."/>
  <!-- 関数format-number()で利用する、数値を文字列かするパターンを定義する -->
  <xsl:decimal-format name="..."/>
  <!-- 名前空間URIが別の名前空間URIに関する別名であることを宣言する -->
  <xsl:namespace-alias stylesheet-prefix="..." result-prefix="..."/>
  <!-- 名前つき属性集合を定義する -->
  <xsl:attribute-set name="...">
    ...
  </xsl:attribute-set>
  <!-- 変数名とその値を定義する -->
  <xsl:variable name="...">...</xsl:variable>
  <!-- 変数名とそのデフォルト値を定義する -->
  <xsl:param name="...">...</xsl:param>
  <!-- パターンにマッチするノードの変換規則を記述する -->
  <xsl:template match="...">
    ...
  </xsl:template>
  <!-- 名前つき変換規則を定義する -->
  <xsl:template name="...">
    ...
  </xsl:template>
</xsl:stylesheet>

xsl:template要素

XSLT文書で最も重要なものは、変換規則を記述するtemplate要素です。ここで、xsl:template要素について、詳しく紹介しましょう。

xsl:template要素は、内容に結果ツリーを記述します。match属性とname属性の何れかが必須の属性であり、name属性が指定されている場合は、属性値を使って、xsl:call-template要素から明示的に参照可能となります。一方、match属性が指定されている場合は、属性値のXPathにマッチしたノードを、結果ツリーに変換する規則として機能します。

リスト2のXSLT文書では、三つのテンプレートが定義されています。最初のものは、match属性値にルート・ノードが指定されており、文書全体を内容のツリー構造に変換するテンプレートです。リスト2では、結果ツリーのルート要素がnamelist要素であり、その子要素にmale要素とfemale要素を記述しました。何れの要素の場合も、内容にはxsl:apply-templates要素が現れています。

xsl:apply-templatesは、select属性を持ち、値に対応するノード集合に対応するテンプレートが当該箇所に挿入される。

male要素の子要素であるxsl:apply-templates要素の場合は、select="/address/item[@sex='male']" が指定されており、マッチする全てのノードに対して、再帰的にテンプレート2が適用され、その結果が挿入されることになります。同様に、female要素の子要素には、テンプレート3の結果が挿入されます。

テンプレート2は、ソースツリーのsex属性の値がmaleであるitem要素にマッチするテンプレートです。内容はcust要素で、その内容にはxsl:value-of要素が指定されています。xsl:value-of要素はselect属性を持ち、マッチするパターンに対応するテキストを結果ツリーのテキスト・ノードに挿入します。すなわち、select属性に要素ノードの集合が指定されれば、その子孫のテキストノードであり、属性ノードが指定されれば、その値が結果ツリーのテキスト・ノードに挿入されることになります。

繰り返し - xsl:for-each要素

xsl:template要素の子要素として、xsl:value-of要素を紹介したが、他にも多くの要素が定義されています。それら全てを説明する余裕はありませんが、一部の要素については本稿でも紹介します。最初に紹介するのは、繰り返し構造を記述するxsl:for-each要素です。

xsl:for-each要素は、select属性の値にマッチするノードが存在する限り、内容を繰り返します。リスト7は、リスト1を、XHTML 1.1文書のテーブルに変換するものです。

リスト7. xsl:value-ofの例(XSLTDemo2.xsl)

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns="http://www.w3.org/1999/xhtml">
                
    <!-- 結果ツリーの出力方法 -->
    <xsl:output method="xml" encoding="UTF-8" indent="yes"
                doctype-public="-//W3C//DTD XHTML 1.1//EN"
                doctype-system="http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd" />
    <!-- テンプレート -->
    <xsl:template match="/">
        <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" >
        <head>
            <meta http-equiv="content-type" content="application/xhtml+xml; charset=UTF-8" />
            <title>顧客リスト</title>
        </head>
        <body>
            <table border="1">
                <!-- 繰り返し -->
                <xsl:for-each select="address/item">
                    <tr>
                        <th><xsl:apply-templates select="name"/></th>
                        <!-- 繰り返し -->
                        <xsl:for-each select="access">
                            <td><xsl:apply-templates/></td>
                        </xsl:for-each>
                    </tr>
                </xsl:for-each>
            </table>
        </body>
        </html>
    </xsl:template>
</xsl:stylesheet>

リスト7では、xsl:output要素に、XHTML 1.1の文書型の、公開識別子とシステム識別子を指定しいます。この情報に基づいて、DTD宣言が結果ツリーに挿入されます。

尚、XHTMLもXML文書であるので、HTML 4向けのoutput method="html"は指定していません。また、文字符号化方法にはUTF-8を明示的に指定し、結果ツリーの出力でインデントをとるように指定しました。このスタイルシートを指定してリスト3を実行すると、結果ツリーはリスト8のようになります。実際は改行されるのみでインデントはとられませんが、見やすくするために適宜スペースを挿入してあります。

リスト8. リスト7による結果ツリー

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
    "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja">
    <head>
        <meta content="text/html; charset=UTF-8" http-equiv="content-type" />
        <title>顧客リスト</title>
    </head>
    <body>
        <table border="1">
            <tr>
                <th>菅井 学</th>
                <td></td>
                <td>http://www.nextindex.net/java/</td>
            </tr><tr>
                <th>鈴木 竜広</th>
                <td>tsuzuki@hoge.foo.bar</td>
            </tr><tr>
                <th>栃原 宏枝</th>
                <td>090-xxxx-xxxx</td>
            </tr>
        </table>
    </body>
</html>

条件分岐 - xsl:if要素とxsl:choose要素

XSTLには、条件によって処理を変更する要素も用意されています。IF-THEN型の場合はxsl:if要素を用い、スイッチ型の条件分岐はxsl:choose要素を用いることになります。

xsl:if要素は、test属性に指定された式を評価して、真であれば内容のテンプレートを実行し、偽であればなにもしません。リスト9は、リスト7に性別のカラムを追加したものです。sex属性の値が"male"であれば「男性」、"female"でれば「女性」と出力します。

xsl:choose要素は、子要素にxsl:when要素を持ち、そのtest属性の値を評価して、実行するテンプレートを選択します。全てのxsl:when要素のtest属性値が真でなければ、xsl:otherwise要素の内容が実行されます。xsl:when要素が真でなく、xsl:otherwise要素が存在しない場合は、なにもしません。リスト9では、xsl:variable要素を用いて変数$kindを定義して、その値に応じて対応する文字列を付加しています。

ソート - xsl:sort要素

XSLTで定義されている要素には、他にもいろいろありますが、最後にソート要素を紹介します。xsl:sort要素は、xsl:apply-templates要素又はxsl:for-each要素の子供として定義され、複数記述することで、一時ソートキー、二次ソートキーとして働きます。属性には、表8に挙げるもものが定義されています。

表8. xsl:sort要素の属性
属性概要
selectソートキー
lang言語
data-type
  • "text"...lang属性で指定された言語の辞書順
  • "number"...数値に変換した結果の数値順
order
  • "ascending"...昇順(デフォルト)
  • "descending"...降順
case-order
  • "upper-first"...lang="en"などの場合に、大文字を先にソートする
  • "lower-first"...小文字を先にソートする

リスト9では、name要素の文字コードの降順にソートしています。

リスト9. 条件分岐とソートの例(XSLTDemo3.xsl)

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns="http://www.w3.org/1999/xhtml">
                
    <!-- 結果ツリーの出力方法 -->
    <xsl:output method="xml" encoding="UTF-8" indent="yes"
                doctype-public="-//W3C//DTD XHTML 1.1//EN"
                doctype-system="http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd" />
    <!-- テンプレート -->
    <xsl:template match="/">
        <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" >
        <head>
            <meta http-equiv="content-type" content="application/xhtml+xml; charset=UTF-8" />
            <title>顧客リスト</title>
        </head>
        <body>
            <table border="1">
                <!-- 繰り返し -->
                <xsl:for-each select="address/item">
                    <!-- ソート指定 -->
                    <xsl:sort select="./name" order="descending"/>
                    <tr>
                        <th><xsl:apply-templates select="name"/></th>
                        <!-- 条件分岐 -->
                        <xsl:if test="@sex='male'">
                            <td>男性</td>
                        </xsl:if>
                        <xsl:if test="@sex='female'">
                            <td>女性</td>
                        </xsl:if>
                        <!-- 繰り返し -->
                        <xsl:for-each select="access">
                            <td>
                                <!-- 変数定義 -->
                                <xsl:variable name="kind" select="@kind"/>
                                <!-- 条件分岐 -->
                                <xsl:choose>
                                    <xsl:when test="$kind='email'">email: </xsl:when>
                                    <xsl:when test="$kind='tel'">tel: </xsl:when>
                                    <xsl:otherwise>others: </xsl:otherwise>
                                </xsl:choose>
                                <xsl:apply-templates/>
                            </td>
                        </xsl:for-each>
                    </tr>
                </xsl:for-each>
            </table>
        </body>
        </html>
    </xsl:template>
</xsl:stylesheet>

リスト9 の XSLT 文書で、リスト1 の XML 文書を処理すると、リスト10のようになります。使ったアプリケーションはリスト3のものです。

リスト10. XSLTDemo3.xslの処理結果

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
   "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja">
    <head>
        <meta content="text/html; charset=UTF-8" http-equiv="content-type" />
        <title>顧客リスト</title>
    </head>
    <body>
        <table border="1">
            <tr>
                <th>鈴木 竜広</th>
                <td>男性</td>
                <td>email: tsuzuki@hoge.foo.bar</td>
            </tr>
            <tr>
                <th>栃原 宏枝</th>
                <td>女性</td>
                <td>tel: 090-xxxx-xxxx</td>
            </tr>
            <tr>
                <th>菅井 学</th>
                <td>男性</td>
                <td>email: </td>
                <td>others: http://www.nextindex.net/java/</td>
            </tr>
        </table>
    </body>
</html>

XSLT 1.0では、以上で挙げた要素や属性のほかにも、多くのものが定義されています。より詳細な定義は、W3CのXSLT 1.0仕様書を参照ください。



Copyright © 2003 SUGAI, Manabu. All Rights Reserved.
SEO [PR] !uO z[y[WJ Cu