Xalan 2.7 中缺少字符串函数,使用 java.lang.String 代替?

发布于 09-17 22:19 字数 1825 浏览 10 评论 0原文

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

行导致此异常:

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

结果:

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 函数?我测试了 ,确实:结果是 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 使用标准 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) 函数?这个startIndex、endIndex函数看起来像java.lang.String的substring方法是巧合吗?

为什么当我使用 fn:string-length 函数时会收到 NoSuchMethodError 错误?

这里出了点问题,而且显然与 XPath 1.0 与 2.0 无关......

I am using Xalan 2.7.0 (as bundled with Apache FOP 1.0) and have problems when using string functions.

The line <xsl:value-of select="fn:replace('test', 't', '*')"/> results in this exception:

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')"/> results in:

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)

Now this is weird! Why does Xalan look for a stringLength function on java.lang.String? I tested <xsl:value-of select="fn:substring('foobar', 2, 3)"/>, and indeed: the result is o, so the arguments were used as startIndex, endIndex (like java.lang.String.substring()) instead of XPath's fn:substring(string, start, length) funcion.

So I think that Xalan is somehow missing its XPath function library and using the regular String class instead. I confirmed this by calling the non-existing function fn:index-of('foobar', 'bar') which works fine and maps to java.lang.String.indexOf(str).

Why does Xalan do that? And how can I fix it?

System info: Xalan uses the standard Mac OS X 10.6.4 Java version, 1.6.0_20.

Update

Okay, leave aside the replace() function for a moment. Shouldn't Xalan, being an XSLT 1.0 processor, implement the XPath 1.0 function substring (string, startIndex, length) and not the (string, startIndex, endIndex) function I see in my expirements? Is it coincidence that this startIndex, endIndex function looks like the substring method of java.lang.String?

And why do I get a NoSuchMethodError when I use the fn:string-length function?

Something's wrong here, and it clearly isn`t about XPath 1.0 vs 2.0...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

迎风吟唱2024-09-24 22:19:21

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>

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

replace() is an XSLT 2.0 function. Xalan is an XSLT 1.0 processor.

You can simulate the replace() function with a template like this from @Ektron Doug D:

<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>

Keep in mind that this XSLT 1.0 solution is a very simple find/replace. The XSLT 2.0 function replace() can use REGEX patterns for the "find" expression.

墨小沫ゞ2024-09-24 22:19:21

当旧的 Xalan 是唯一的选择时,这个对我有用:

<xsl:value-of 
   select="java:replaceAll(java:java.lang.String.new(ContactInfo/telephone/text()),'[^0-9]','')"/>

When old Xalan is the only option, this one works for me:

<xsl:value-of 
   select="java:replaceAll(java:java.lang.String.new(ContactInfo/telephone/text()),'[^0-9]','')"/>
み青杉依旧2024-09-24 22:19:21

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

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

如果函数调用中存在函数名称
表达式不是 NCName(即如果
它包含一个冒号),那么它是
视为对分机的呼叫
功能。 FunctionName 已展开
使用命名空间的名称
评估声明
上下文。

The result from substring('foobar', 2, 3) (Do note: without namespace) should be oob.

In XSLT 1.0 any function call with prefix will be interpreted as an extension call. From http://www.w3.org/TR/xslt#section-Extension-Functions

If a FunctionName in a FunctionCall
expression is not an NCName (i.e. if
it contains a colon), then it is
treated as a call to an extension
function. The FunctionName is expanded
to a name using the namespace
declarations from the evaluation
context.

年华零落成诗2024-09-24 22:19:21

现在这很奇怪!为什么 Xalan 看起来
对于 stringLength 函数
java.lang.String?我测试过
,而且确实:结果是 o,所以
参数用作 startIndex,
结束索引(如
java.lang.String.substring()) 代替
XPath 的 fn:substring(string, start,
长度)函数。

所以我认为 Xalan 是某种
缺少 XPath 函数库并且
使用常规 String 类
反而。我通过电话确认了这一点
不存在的函数
fn:index-of('foobar', 'bar') 其中
工作正常并映射到
java.lang.String.indexOf(str)。

Xalan 为何这么做?我怎样才能
修复它吗?

  1. Xalan 为何这么做?因为 Xalan 是 XSLT 1.0 处理器,任何兼容的 XSLT 1.0 处理器仅支持 XPath 1.0。 replace()是 XPath 2.0 的标准功能,必须在任何兼容的 XSLT 2.0 处理器中实现。

  2. 我该如何解决这个问题?通过使用 XSLT 2.0 处理器,例如 Saxon 9.xAltovaXML2010。或者编写一个命名的递归 在 XSLT 1.0 中进行简单替换。

Now this is weird! Why does Xalan look
for a stringLength function on
java.lang.String? I tested
, and indeed: the result is o, so
the arguments were used as startIndex,
endIndex (like
java.lang.String.substring()) instead
of XPath's fn:substring(string, start,
length) funcion.

So I think that Xalan is somehow
missing its XPath function library and
using the regular String class
instead. I confirmed this by calling
the non-existing function
fn:index-of('foobar', 'bar') which
works fine and maps to
java.lang.String.indexOf(str).

Why does Xalan do that? And how can I
fix it?

  1. Why does Xalan do that? Because Xalan is XSLT 1.0 processor and any compliant XSLT 1.0 processor only supports XPath 1.0. replace() is a standard function of XPath 2.0 and must be implemented in any compliant XSLT 2.0 processor.

  2. And how can I fix it? By using an XSLT 2.0 processor like Saxon 9.x or AltovaXML2010. Or write a named, recursive <xsl:template> to do simple replacements in XSLT 1.0.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文