5. 変数とパラメータ
- 5.1 変数とパラメータ
- 5.2 xsl:copy-of を用いた変数とパラメータの使用
- 5.3 変数とパラメータの宣言箇所による違い
- 5.4 テンプレートへのパラメータの引き渡し
この章においては、以下の XML 文書を用いて変数とパラメータについてみていきたいと思います。
people.xml |
<?xml version="1.0"?> <people> <person>Kevin Shields</person> <person>Trent Reznor</person> </people> |
5.1 変数とパラメータ
<xsl:variable name = qname select = expression> <!-- Content: template --> </xsl:variable>
<xsl:param name = qname select = expression> <!-- Content: template --> </xsl:param>
変数の宣言は xsl:variable 要素、パラメータの宣言は xsl:param 要素を用いて行います。変数およびパラメータの値は式の中で参照することができます。変数とパラメータは、 パラメータの場合には XSLT スタイルシートで結び付けられる値がデフォルト値にすぎない、 という点で異なります。 つまり、XSLT スタイルシートやテンプレートを呼び出す際にパラメータに値を渡すことができます。
xsl:variable と xsl:param のどちらも、name 属性は必須で、属性値として変数の名前を指定します。宣言した変数はこの name 属性の値を用いて参照します。たとえば、name = "sample" と宣言した変数は、$sample として参照することができます。
変数の値の指定方法には以下の 2通りがあります。
- select 属性の属性値で指定する
select 属性の値は式で指定します。変数の値はこの属性値を評価した結果得られるオブジェクトが格納されます。select 属性を指定した場合は要素内に何も含むことはできません。
- 要素の内容で指定する
select 属性を持たない場合、要素内にテンプレートを記述することで変数の値を指定します。変数には結果ツリーフラグメントというデータ型のオブジェクトが格納されます。結果ツリーフラグメントは、結果ツリーの断片を表し、ルートノードを一つだけ含むノード集合と同様に扱われます。よって、テンプレートを適用した結果生成されたノード集合のメンバが属性ノードまたは名前空間ノードの場合はエラーとなります。これは、ルートノードがそれらのノードを子として持つことができないためです。
要素の内容が空であり、select 属性を持たない場合、変数の値は空文字列になります。
<xsl:variable name="n">2</xsl:variable> ... <xsl:value-of select="person[$n]"/>
このようにすると、1番目の person 要素の文字列値が出力されてしまいますが、どうしてでしょうか。
すでに述べたように要素の内容で変数の値を指定すると、変数には結果ツリーフラグメント型でオブジェクトが格納されます。つまり、上記の例では変数 n に 2 というテキストノードを子として持つ、ルートノードだけを含むノード集合と同等に扱われます。 また、[ ] の中の式を評価した結果がノード集合である場合、 そのノード集合が空集合でなければ評価結果は true になるので、 person[$n] という式を評価した結果は、 カレントノードの子要素 person すべてを含むノード集合となります。
xsl:value-of の select 属性で指定されたノード集合は string 型に変換されます。 node-set 型から string 型への変換は、 そのノード集合に含まれるノードのうちドキュメント順で一番目にあたるノードの文字列値を得ることで行なわれます。
以上によって、 「最初の person 要素の値が出力されてしまう」という結果になるのです。
2番目の要素を指定するには以下のようにします。
<xsl:variable name="n" select="2"></xsl:variable> <xsl:template match="people"> <xsl:value-of select="person[$n]"/> </xsl:template>
<xsl:variable name="n">2</xsl:variable> <xsl:template match="people"> <xsl:value-of select="person[position()=$n]"/>, </xsl:template>
上記のテンプレートのいずれかを people.xml に適用すると以下の出力を得られます。
Trent Reznor