スペース文字の数であるテキスト値を含む変数を作成したいのですが、文字数は実行時までわかりません。これは何度も行う必要があるので、非常にうまく機能するものを使用したいと思います。
1つのオプションは、以前に宣言されたノードのsubstring()関数ですが、これにより、長さが元のテキストの長さ以下に制限されます。
もう1つは、concat()関数で再帰テンプレートを使用することですが、パフォーマンスへの影響についてはよくわかりません。
非常にうまく機能するこれを行う方法は何ですか?
再帰を使用して分割統治することができます。これにより、実行時の注文コスト(log N)がわかります。または、XSLTプロセッサが末尾再帰の最適化を実装している場合は、末尾再帰ソリューションを使用して、大規模な安全性を高めることができます。これが2つの解決策です...
<xsl:template name="spaces">
<xsl:param name="count" />
<xsl:choose>
<xsl:when test="$count <= 10">
<xsl:value-of select="substring(' ',1,$count)" />
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="spaces">
<xsl:with-param name="count" select="$count idiv 2" />
</xsl:call-template>
<xsl:call-template name="spaces">
<xsl:with-param name="count" select="$count - ($count idiv 2)" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="spaces">
<xsl:param name="count" />
<xsl:choose>
<xsl:when test="$count <= 10">
<xsl:value-of select="substring(' ',1,$count)" />
</xsl:when>
<xsl:otherwise>
<xsl:text> </xsl:text>
<xsl:call-template name="spaces">
<xsl:with-param name="count" select="$count - 10" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
4000スペースなどの長さのグローバル変数を作成します。次に、目的の文字列が4000スペース未満の場合は、substring();を使用します。それよりも大きい場合は、ダーキンが概説した再帰的アプローチを使用します。もちろん2.0では、コードの記述ははるかに簡単ですが、うまく機能するアプローチを選択することは、興味深い小さな問題です。
効率的な(時間とスペースの両方の)XSLT 1.0ソリューションについては、以下を参照してください。