他の人は、変数がどのように不変であるかを既に説明しています。つまり、XSLT には割り当てステートメントがありません (一般的な純粋な関数型プログラミング言語と同様)。
これまでに提案されたソリューションに代わるものがあります。パラメータの受け渡しを回避します (これは XSLT では冗長で見苦しくなりますが、私も認めます)。
<section>
XPath では、現在の要素の前にある要素の数を単純に数えることができます。
<xsl:template name="section">
<span class="title" id="title-{1 + count(preceding-sibling::section)}">
<xsl:value-of select="title"/>
</span>
</xsl:template>
(注: 空白のみのテキスト ノードはスタイルシートから自動的に取り除かれるため、空白コードの書式設定は結果に表示されません。したがって、同じ行に命令を入れる必要はありません。)
( を使用する場合とは対照的に) このアプローチの大きな利点の 1 つposition()
は、現在のノード リストではなく、現在のノードのみに依存することです。なんらかの方法で処理を変更した場合 (たとえば、<xsl:for-each>
セクションだけでなく他の要素も処理した場合)、 の値は必ずしもドキュメント内の要素position()
の位置に対応しなくなります。<section>
一方、count()
上記のように使用すると、常に各<section>
要素の位置に対応します。このアプローチは、コードの他の部分との結合を減らします。これは一般的に非常に良いことです。
count() に代わる方法は、<xsl:number>
命令を使用することです。デフォルトの動作では、同じレベルのすべての同様の名前の要素に番号が付けられます。これはたまたまあなたが望むものです:
<xsl:template name="section">
<xsl:variable name="count">
<xsl:number/>
</xsl:variable>
<span class="title" id="title-{$count}">
<xsl:value-of select="title"/>
</span>
</xsl:template>
これは、冗長性 (属性値テンプレートの中括弧を引き続き使用する場合は、追加の変数宣言が必要) とのトレードオフですが、XPath 式が大幅に簡素化されるため、わずかです。
まだ改善の余地があります。現在のノード リストへの依存関係を削除しましたが、現在のノードにはまだ依存しています。それ自体は悪いことではありませんが、テンプレートを見て現在のノードが何であるかがすぐにはわかりません。私たちが知っているのは、テンプレートの名前が " section
" であることだけです。何が処理されているかを確実に知るには、コードの別の場所を調べる必要があります。しかし、そうである必要はありません。
<xsl:for-each>
and を一緒に使用することに導かれたと感じた場合<xsl:call-template>
(例のように)、一歩下がって<xsl:apply-templates>
代わりに使用方法を考えてください。
<xsl:template match="/doc">
<xsl:apply-templates select="section"/>
</xsl:template>
<xsl:template match="section">
<xsl:variable name="count">
<xsl:number/>
</xsl:variable>
<span class="title" id="title-{$count}">
<xsl:value-of select="title"/>
</span>
</xsl:template>
このアプローチは冗長ではない (と の両方を<xsl:apply-templates/>
置き換える) だけでなく、現在のノードが何であるかがすぐに明らかになります。属性を見るだけで、要素を処理していること、および要素を数えていることがすぐにわかります。<xsl:for-each>
<xsl:call-template/>
match
<section>
<section>
テンプレート ルール (つまり、属性<xsl:template>
を持つ要素)がどのように機能するかについての簡潔な説明については、 「XSLT の仕組み」を参照してください。match