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 ...
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 扩展为名称。