В Xalan 2.7 отсутствуют строковые функции, вместо этого используется java.lang.String? - PullRequest
4 голосов
/ 05 сентября 2010

Я использую 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 ищет stringLength функцию на java.lang.String? Я протестировал <xsl:value-of select="fn:substring('foobar', 2, 3)"/>, и действительно: результат - o, поэтому аргументы использовались как startIndex, endIndex (например, java.lang.String.substring()) вместо fn:substring(string, start, length) функции XPath.

Так что я думаю, что 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(). Разве Xalan, будучи процессором XSLT 1.0, не должен реализовывать подстроку функции XPath 1.0 (string, startIndex, length), а не функцию (string, startIndex, endIndex), которую я вижу по истечении срока действия? Является ли совпадением, что эта функция startIndex, endIndex выглядит как метод подстроки java.lang.String?

И почему я получаю ошибку NoSuchMethodError, когда использую функцию fn:string-length?

Что-то здесь не так, и дело явно не в XPath 1.0 против 2.0 ...

Ответы [ 4 ]

7 голосов
/ 05 сентября 2010

replace() - это функция XSLT 2.0 . Xalan - это XSLT 1.0 процессор.

Вы можете смоделировать функцию replace () с помощью шаблона , подобного этому, от @EktronDoug 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>

Имейте в виду, что это решение XSLT 1.0 очень просто найти / заменить.Функция XSLT 2.0 replace () может использовать шаблоны REGEX для выражения «find».

4 голосов
/ 10 мая 2012

Когда старый Xalan - единственный вариант, этот работает для меня:

<xsl:value-of 
   select="java:replaceAll(java:java.lang.String.new(ContactInfo/telephone/text()),'[^0-9]','')"/>
3 голосов
/ 06 сентября 2010

Результат от substring('foobar', 2, 3) ( Примечание: без пространства имен ) должен быть oob.

В XSLT 1.0 любой вызов функции с префиксом будет интерпретироваться как вызов расширения.С http://www.w3.org/TR/xslt#section-Extension-Functions

Если имя-функции в выражении FunctionCall не является NCName (т. Е. Если оно содержит двоеточие), то оно обрабатывается как вызов функции расширения.Имя_функции раскрывается до имени с помощью объявлений пространства имен из контекста оценки.

1 голос
/ 06 сентября 2010

Теперь это странно!Почему Xalan ищет функцию stringLength в java.lang.String?Я проверял и действительно: результат равен 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сделай это?И как я могу это исправить?

  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.x или AltovaXML2010 .Или напишите именованное, рекурсивное <xsl:template> для выполнения простых замен в XSLT 1.0.

...