5

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)

今、これは奇妙です!stringLengthXalanがで関数を探すのはなぜjava.lang.Stringですか?私はテストしました<xsl:value-of select="fn:substring('foobar', 2, 3)"/>が、実際、結果はoであるため、引数はXPathの関数の代わりにstartIndex, endIndex(のように)使用されました。java.lang.String.substring()fn:substring(string, start, length)

したがって、XalanにはXPath関数ライブラリがなく、代わりに通常のStringクラスを使用していると思います。fn:index-of('foobar', 'bar')正常に動作し、にマップされる存在しない関数を呼び出すことで、これを確認しましたjava.lang.String.indexOf(str)

Xalanがそれを行うのはなぜですか?そして、どうすればそれを修正できますか?

システム情報:Xalanは標準のMac OS X10.6.4Javaバージョン1.6.0_20を使用します。

アップデート

さて、replace()関数をしばらく脇に置いておきます。XSLT 1.0プロセッサであるXalanは、有効期限に表示される関数ではなく、XPath 1.0関数のサブストリング を実装するべきではありませんか?このstartIndex、endIndex関数がの部分文字列メソッドのように見えるのは偶然ですか?(string, startIndex, length)(string, startIndex, endIndex)java.lang.String

fn:string-lengthまた、関数を使用するとなぜNoSuchMethodErrorが発生するのですか?

ここで何かがおかしいです、そしてそれは明らかにXPath1.0対2.0についてではありません...

4

4 に答える 4

8

replace()XSLT2.0関数です 。XalanXSLT1.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>

このXSLT1.0ソリューションは、非常に単純な検索/置換であることに注意してください。XSLT 2.0関数replace()は、「find」式にREGEXパターンを使用できます。

于 2010-09-05T12:57:04.673 に答える
4

古いXalanが唯一のオプションである場合、これは私にとって有効です。

<xsl:value-of 
   select="java:replaceAll(java:java.lang.String.new(ContactInfo/telephone/text()),'[^0-9]','')"/>
于 2012-05-10T19:14:47.370 に答える
3

substring('foobar', 2, 3)注:名前空間なし)の結果は、である必要がありますoob

XSLT 1.0では、プレフィックス付きの関数呼び出しはすべて拡張呼び出しとして解釈されます。http://www.w3.org/TR/xslt#section-Extension-Functionsから

FunctionCall式のFunctionNameがNCNameでない場合(つまり、コロンが含まれている場合)、拡張関数の呼び出しとして扱われます。FunctionNameは、評価コンテキストからの名前空間宣言を使用して名前に展開されます。

于 2010-09-05T21:32:07.460 に答える
1

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.

于 2010-09-06T16:43:22.357 に答える