A. Shah
A. Shah

Reputation: 37

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

I have the following partly generated xsl as well as an extension class with an overloaded method. Xalan is able to transform it fine. However, Saxon produces the following error. I'm not sure why it is not able to bind to the method with two String parameters. Any help is appreciated.

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 Extension class methods

/**`
 *********************************************************************************************************** 
 * 
 * @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);
}

Upvotes: 0

Views: 456

Answers (1)

Michael Kay
Michael Kay

Reputation: 163322

There's no particular reason to expect Saxon and Xalan to work the same way here: extension functions are left completely implementation-defined in the spec, and Saxon's approach is designed to work with the much more elaborate type system of XSLT 2.0.

Saxon's mechanism attempts to distinguish polymorphic methods, but it can only do so when sufficient static type information is available. There isn't a single type declaration in your code, as far as I can see, so Saxon hasn't got very much to go on. I would have guessed that a function called convertToNumber returns a number, but it actually appears to return an untyped text node, and that leaves nothing to go on at all. Declaring the return type of convertToNumber as xs:string (if that's really what you want!) might be enough.

Upvotes: 1

Related Questions