Xalan 2.7 中缺少字符串函数,改用 java.lang.String 吗?
Posted
技术标签:
【中文标题】Xalan 2.7 中缺少字符串函数,改用 java.lang.String 吗?【英文标题】:String functions missing in Xalan 2.7, java.lang.String used instead? 【发布时间】:2011-04-08 09:54:54 【问题描述】:我正在使用 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)
<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)
现在这很奇怪!为什么 Xalan 会在 java.lang.String
上寻找 stringLength
函数?我测试了<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 function substring (string, startIndex, length)
而不是我在过期时看到的 (string, startIndex, endIndex)
函数吗?这个startIndex、endIndex函数看起来像java.lang.String
的substring方法是不是巧合?
为什么我在使用fn:string-length
函数时会收到 NoSuchMethodError?
这里出了点问题,显然不是关于 XPath 1.0 与 2.0...
【问题讨论】:
好问题 (+1)。请参阅我的答案以获得解释。 您为前缀 fn: 使用什么命名空间?当您使用<xsl:value-of select="string-length('foobar')"/>
(即string-length()
上没有命名空间前缀)时,它是否仍然给出NoSuchMethodException?
LarsH: 命名空间是w3.org/2005/02/xpath-functions,但正如 Alejandro 在下面写的,我必须省略 fn: 前缀。谢谢!
@Jens-Bannmann、@LarsH、@Alejandro、@Mads-Hansen:有人对@Mads-Hansen 和我的答案投了反对票——这两个答案都是正确的?!?让我们至少解释一下投票失败的原因。如果 OP 一夜之间在他最初的问题中添加了新问题,我们应该醒来发现我们的正确答案被否决了吗?
@Dimitre:+1 唤醒评论!奇怪的事情发生在 SO... 至少我们将 XSL 标记保持为 XSLT 标记的同义词。
【参考方案1】:
replace()
是一个 XSLT 2.0 函数。 Xalan 是一个 XSLT 1.0 处理器。
你可以用template like this from @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>
请记住,这个 XSLT 1.0 解决方案是一个非常简单的查找/替换。 XSLT 2.0 函数 replace() 可以将 REGEX 模式用于“查找”表达式。
【讨论】:
【参考方案2】:当旧的 Xalan 是唯一的选择时,这个对我有用:
<xsl:value-of
select="java:replaceAll(java:java.lang.String.new(ContactInfo/telephone/text()),'[^0-9]','')"/>
【讨论】:
【参考方案3】:substring('foobar', 2, 3)
(注意:没有命名空间)的结果应该是oob
。
在 XSLT 1.0 中,任何带有前缀的函数调用都将被解释为扩展调用。来自http://www.w3.org/TR/xslt#section-Extension-Functions
如果 FunctionCall 中的 FunctionName 表达式不是 NCName(即,如果 它包含一个冒号),那么它是 被视为对分机的呼叫 功能。 FunctionName 展开 使用命名空间的名称 评估声明 上下文。
【讨论】:
【参考方案4】:现在这很奇怪!为什么Xalan看起来 对于 stringLength 函数 java.lang.String?我测试过 ,而且确实:结果是 o,所以 参数被用作 startIndex, endIndex(如 java.lang.String.substring()) 代替 XPath 的 fn:substring(string, start, 长度)函数。
所以我认为 Xalan 在某种程度上 缺少它的 XPath 函数库和 使用常规 String 类 反而。我通过致电确认了这一点 不存在的功能 fn:index-of('foobar', 'bar') 其中 工作正常并映射到 java.lang.String.indexOf(str).
Xalan 为什么要这样做?我怎么能 修好吗?
Xalan 为什么要这样做?因为 Xalan 是 XSLT 1.0 处理器,而任何兼容的 XSLT 1.0 处理器都只支持 XPath 1.0。 replace()
是 XPath 2.0 的标准功能,必须在任何兼容的 XSLT 2.0 处理器中实现。
我该如何解决它?通过使用 XSLT 2.0 处理器,如 Saxon 9.x 或 AltovaXML2010。或者编写一个命名的递归 <xsl:template>
在 XSLT 1.0 中进行简单的替换。
【讨论】:
以上是关于Xalan 2.7 中缺少字符串函数,改用 java.lang.String 吗?的主要内容,如果未能解决你的问题,请参考以下文章
如何防止具有 META-INF\services\javax.xml.transform.TransformerFactory 的 xalan.jar 接管 Xalan 实现中内置的 JDK 1.6?
如何将字符串中的数字转换为 python 2.7 中的完整函数?