0

func:functionEXSLT の要素を使用して、スタイルシートで使用する「三項演算子」拡張関数を実装しようとしました。互換性の理由から、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 ヒープ スペース) をスローするだけです。この関数に送信するデータ セットはかなり小さいため、オーバーフローが発生する場所と、スタック サイズを増やす必要がある理由がわかりません。

私は何を間違っていますか?

4

1 に答える 1

0

「三項演算子」拡張機能を実装してみた

否定述語変数チェックを伴う位置述語の共用体をelseステートメントとして使用します。

//var[1] | //var[not //var]

相互に排他的な式の連結を三項イディオムとして使用します。

concat("(",substring(translate(., "()-", ""), 1, 3), ")", substring(translate(., "()-", ""), 4, 3), "-", substring(translate(., "()-", ""), 7, 4)))

XPath の number(true()) は 1、number(false()) は 0 であり、substring() 関数の 2 番目の引数が文字列の実際の長さより大きい場合、空の文字列が返されます。したがって、substring($s1, number(not($condition))*string-length($s1)+1) は、$condition が true の場合は $s1 を返し、それ以外の場合は空の文字列を返します。このような 2 つの式を相互に排他的な方法で連結すると、条件付き文字列式が得られます。

参考文献

于 2015-12-02T05:44:27.263 に答える