func:function
EXSLT の要素を使用して、スタイルシートで使用する「三項演算子」拡張関数を実装しようとしました。互換性の理由から、XSLT 1.0 を使用する必要があります。私はこれを思いついた:
<func:function name="myext:ternary">
<xsl:param name="expr" />
<xsl:param name="ifTrue" />
<xsl:param name="ifFalse" />
<func:result>
<xsl:choose>
<xsl:when test="boolean($expr)"><xsl:value-of select="$ifTrue"/></xsl:when>
<xsl:otherwise><xsl:value-of select="$ifFalse" /></xsl:otherwise>
</xsl:choose>
</func:result>
</func:function>
どこで使用しても問題なく動作します。ただし、substring-after-last 関数も実装しようとしました (ここから)。このコードは正常に動作します:
<func:function name="myext:substring-after-last">
<xsl:param name="string" select="''"/>
<xsl:param name="delimiter" select="$d" />
<func:result>
<xsl:choose>
<xsl:when test="contains($string, $delimiter)">
<xsl:value-of select="myext:substring-after-last(substring-after($string, $delimiter), $delimiter)"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$string"/>
</xsl:otherwise>
</xsl:choose>
</func:result>
</func:function>
この方法でも機能します:
[…]
<func:result>
<xsl:if test="not(contains($string, $delimiter))">
<xsl:value-of select="$string"/>
</xsl:if>
<xsl:if test="not($string='')">
<xsl:value-of select="myext:substring-after-last(substring-after($string, $delimiter), $delimiter)"/>
</xsl:if>
</func:result>
</func:function>
…しかし、「三項」関数を使用して実装しようとすると、機能しません。
これは機能しません:
<func:result>
<xsl:value-of select="myext:ternary(
contains($string, $delimiter) and not($string = ''),
myext:substring-after-last(substring-after($string, $delimiter), $delimiter),
$string
)"/>
</func:result>
この方法により、スタイルシートで次のエラーがスローされます。
Error at xsl:apply-templates on line 49 of file:/[my_main_file].xsl:
Too many nested apply-templates calls
Transformation failed: Run-time errors were reported
-Xss16m スイッチを使用して Java のスタック サイズを増やそうとしましたが、Saxon が OutOfMemoryError (Java ヒープ スペース) をスローするだけです。この関数に送信するデータ セットはかなり小さいため、オーバーフローが発生する場所と、スタック サイズを増やす必要がある理由がわかりません。
私は何を間違っていますか?