Saxon error : There is more than one method matching the function call

Saxon error : There is more than one method matching the function call

我有以下部分生成的 xsl 以及带有重载方法的扩展 class。 Xalan 能够很好地转换它。但是,Saxon 会产生以下错误。我不确定为什么它不能绑定到带有两个 String 参数的方法。感谢任何帮助。

There is more than one method matching the function call Compare:lessThan, and there is insufficient type information to determine which one should be used

<e>
 <xsl:attribute name="n">dateTime</xsl:attribute>
    <xsl:attribute name="m">f</xsl:attribute>`enter code here`
    <xsl:attribute name="d">f</xsl:attribute>
    <xsl:attribute name="field">t</xsl:attribute>
    <xsl:variable name="index" select="indexr:getIndex($Indexr,'Timezone|dateTime ')"/>
    <xsl:variable name="__resOfRule">
      <xsl:variable name="Val1">
        <xsl:value-of select="$_root/Timezone[1]/one[1]"/>
      </xsl:variable>
      <xsl:variable name="source0">
        <xsl:variable name="fieldData">
          <xsl:choose>
            <xsl:when test="string-length($Val1) = 0">
              <xsl:value-of select='string("M")'/>
            </xsl:when>
            <xsl:otherwise>
              <xsl:value-of select="TXSLTFormater:validateNTrimSourceString(concat('&lt;element data=&quot;',$Val1,'&quot;',' spath=&quot;Timezone|one&quot;',' sIntr=&quot;2&quot;',' sPres=&quot;1&quot;',' justify=&quot;R&quot;',' isDiscriminatorField=&quot;false&quot;',' do3_10_3WsProcessing=&quot;false&quot;',' WsProcessingMode=&quot;XML&quot;',' tpath=&quot;Timezone|dateTime&quot;/&gt;'), 'Y', $ErrorListener,$index)" xmlns:TXSLTFormater="com.contivo.runtime.common.TXSLTFormater"/>
            </xsl:otherwise>
          </xsl:choose>
        </xsl:variable>
        <xsl:value-of select="string($fieldData)"/>
      </xsl:variable>
      <xsl:variable name="source1" select="substring($source0, 2)"/>
      <xsl:variable name="source2" select="substring($source0, 1, 1)"/>
      <xsl:variable name="Val2">
        <xsl:value-of select="$_root/Timezone[1]/two[1]"/>
      </xsl:variable>
      <xsl:variable name="source3">
        <xsl:variable name="fieldData">
          <xsl:choose>
            <xsl:when test="string-length($Val2) = 0">
              <xsl:value-of select='string("M")'/>
            </xsl:when>
            <xsl:otherwise>
              <xsl:value-of select="TXSLTFormater:validateNTrimSourceString(concat('&lt;element data=&quot;',$Val2,'&quot;',' spath=&quot;Timezone|two&quot;',' sIntr=&quot;1&quot;',' sPres=&quot;200&quot;',' justify=&quot;R&quot;',' isDiscriminatorField=&quot;false&quot;',' do3_10_3WsProcessing=&quot;false&quot;',' WsProcessingMode=&quot;XML&quot;',' tpath=&quot;Timezone|dateTime&quot;/&gt;'), 'Y', $ErrorListener,$index)" xmlns:TXSLTFormater="com.contivo.runtime.common.TXSLTFormater"/>
            </xsl:otherwise>
          </xsl:choose>
        </xsl:variable>
        <xsl:value-of select="string($fieldData)"/>
      </xsl:variable>
      <xsl:variable name="source4" select="substring($source3, 2)"/>
      <xsl:variable name="source5" select="substring($source3, 1, 1)"/>
      <xsl:variable name="target0">
        <xsl:choose>
          <xsl:when test="(ctvf:convertToNumber($source2) = 'M')">
            <xsl:choose>
              <xsl:when test="(concat('a', $source5) = concat('a', 'M'))">
                <xsl:choose>
                  <xsl:when test="((Compare:lessThan(ctvf:convertToNumber($source1),$source4)))">
                    <xsl:value-of select="&quot;true&quot;"/>
                  </xsl:when>
                  <xsl:otherwise>
                    <xsl:value-of select="&quot;false&quot;"/>
                  </xsl:otherwise>
                </xsl:choose>
              </xsl:when>
              <xsl:otherwise>
                <xsl:value-of select="TXSLTFormater:WriteOut($errorFile, string($source4))" xmlns:TXSLTFormater="com.contivo.runtime.common.TXSLTFormater"/>
              </xsl:otherwise>
            </xsl:choose>
          </xsl:when>
          <xsl:otherwise>
            <xsl:value-of select="TXSLTFormater:WriteOut($errorFile, string($source1))" xmlns:TXSLTFormater="com.contivo.runtime.common.TXSLTFormater"/>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:variable>
      <xsl:value-of select="$target0"/>
    </xsl:variable>
    <xsl:if test="$__resOfRule != ''">
      <xsl:variable name="__resOfVal">
        <xsl:value-of select="TXSLTFormater:validateNTrimSourceString(concat('&lt;element data=&quot;',$__resOfRule,'&quot;',' tIntr=&quot;1&quot;',' tPres=&quot;203&quot;',' minSize=&quot;19&quot;',' maxSize=&quot;2147483647&quot;', ' facetEnabled=&quot;false&quot;',' tpath=&quot;Timezone|dateTime&quot;/&gt;'), 'N',$ErrorListener,$index)" xmlns:TXSLTFormater="com.contivo.runtime.common.TXSLTFormater"/>
      </xsl:variable>
      <xsl:choose>
        <xsl:when test='substring($__resOfVal, 1, 1) = "M"'>
          <xsl:value-of select="substring($__resOfVal, 2)"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="TXSLTFormater:WriteOut($errorFile, substring($__resOfVal, 2))" xmlns:TXSLTFormater="com.contivo.runtime.common.TXSLTFormater"/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:if>
  </e>
</e>

<xsl:function name="ctvf:convertToNumber">
<xsl:param name="val"/>
<xsl:variable name="strVal" select="string($val)"/>
<xsl:choose>
  <xsl:when test="starts-with($strVal,'M')">
    <xsl:value-of select="$strVal"/>
   </xsl:when>
  <xsl:when test="string(number($strVal)) = 'NaN'">
    <xsl:value-of select="''"/>
   </xsl:when>
  <xsl:otherwise>
    <xsl:value-of select="$strVal"/>
  </xsl:otherwise>
</xsl:choose>
</xsl:function>

`

Java 扩展 class 方法

/**`
 *********************************************************************************************************** 
 * 
 * @param operandA
 * @param operandB
 * 
 * @return
 */
 public static final boolean lessThan(final String operandA, final String operandB)
{
    return (operandA != null) && (operandB != null) && (operandA.compareTo(operandB) < 0);
}

/**
 *********************************************************************************************************** 
 * 
 * @param operandA
 * @param operandB
 * 
 * @return
 */
public static final boolean lessThan(final String operandA, final double operandB)
{
    return lessThan(operandA, String.valueOf(operandB));
}

/**
 *********************************************************************************************************** 
 * 
 * @param operandA
 * @param operandB
 * 
 * @return
 */
public static final boolean lessThan(final double operandA, final String operandB)
{
    return lessThan(String.valueOf(operandA), operandB);
}

没有特别的理由期望 Saxon 和 Xalan 在这里以相同的方式工作:扩展函数在规范中完全由实现定义,并且 Saxon 的方法旨在与更复杂的 XSLT 2.0 类型系统一起工作.

Saxon 的机制试图区分多态方法,但只有在有足够的静态类型信息可用时才能这样做。据我所知,您的代码中没有单一类型声明,因此 Saxon 没有太多可继续的地方。我猜想一个名为 convertToNumber return 的函数是一个数字,但它实际上看起来 return 是一个未类型化的文本节点,并且根本没有任何事情可以继续进行。将 return 类型的 convertToNumber 声明为 xs:string(如果这确实是您想要的!)可能就足够了。