Xalan 2.7中缺少字符串函数,而是使用了java.lang.String?

Jen*_*ann 4 xslt xpath function xalan

我正在使用Xalan 2.7.0(与Apache FOP 1.0捆绑在一起)并且在使用字符串函数时遇到问题.

该行<xsl:value-of select="fn:replace('test', 't', '*')"/>导致此异常:

javax.xml.transform.TransformerException: java.lang.IllegalArgumentException: argument type mismatch
    at org.apache.fop.cli.InputHandler.transformTo(InputHandler.java:302)
Run Code Online (Sandbox Code Playgroud)

<xsl:value-of select="fn:string-length('foobar')"/> 结果是:

javax.xml.transform.TransformerException: java.lang.NoSuchMethodException: For extension function, could not find method java.lang.String.stringLength([ExpressionContext,] ).
    at org.apache.fop.cli.InputHandler.transformTo(InputHandler.java:302)
Run Code Online (Sandbox Code Playgroud)

现在这很奇怪!为什么Xalan会寻找一个stringLength函数java.lang.String?我测试了<xsl:value-of select="fn:substring('foobar', 2, 3)"/>,确实:结果是o,所以参数被用作startIndex, endIndex(比如java.lang.String.substring())而不是XPath的fn:substring(string, start, length)函数.

所以我认为Xalan在某种程度上错过了它的XPath函数库,而是使用了常规的String类.我通过调用不存在的函数fn:index-of('foobar', 'bar')来确认这一点,该函数工作正常并映射到java.lang.String.indexOf(str).

为什么Xalan会这样做?我该如何解决?

系统信息:Xalan使用标准的Mac OS X 10.6.4 Java版本1.6.0_20.

更新

好吧,replace()暂时搁置这个功能.作为一个XSLT 1.0处理器,Xalan不应该实现XPath 1.0函数子字符串 (string, startIndex, length)而不是(string, startIndex, endIndex)我在我的expirements中看到的函数吗?这个startIndex,endIndex函数看起来像子串方法是巧合java.lang.String吗?

为什么我在使用该fn:string-length函数时会得到NoSuchMethodError ?

这里出了点问题,显然不是XPath 1.0 vs 2.0 ...

Mad*_*sen 7

replace()是一个XSLT 2.0函数. Xalan是一个XSLT 1.0处理器.

您可以使用@Ektron Doug D中模板模拟replace()函数:

<xsl:template name="replace-substring">
<xsl:param name="original"/>
<xsl:param name="substring"/>
<xsl:param name="replacement" select="''"/>
<xsl:choose>
    <xsl:when test="contains($original, $substring)">
        <xsl:value-of select="substring-before($original, $substring)"/>
        <xsl:copy-of select="$replacement"/>
        <xsl:call-template name="replace-substring">
            <xsl:with-param name="original" select="substring-after($original, $substring)"/>
            <xsl:with-param name="substring" select="$substring"/>
            <xsl:with-param name="replacement" select="$replacement"/>
        </xsl:call-template>
    </xsl:when>
    <xsl:otherwise>
        <xsl:value-of select="$original"/>
    </xsl:otherwise>
</xsl:choose>
</xsl:template>
Run Code Online (Sandbox Code Playgroud)

请记住,这个XSLT 1.0解决方案是一个非常简单的查找/替换.XSLT 2.0函数replace()可以使用REGEX模式作为"find"表达式.


小智 3

substring('foobar', 2, 3)请注意:没有命名空间)的结果应该是oob

在 XSLT 1.0 中,任何带有前缀的函数调用都将被解释为扩展调用。来自http://www.w3.org/TR/xslt#section-Extension-Functions

如果 FunctionCall 表达式中的 FunctionName 不是 NCName(即,如果它包含冒号),则将其视为对扩展函数的调用。使用求值上下文中的命名空间声明将 FunctionName 扩展为名称。