Saxon: невозможно вызвать статический метод, ожидающий String с параметром xs: string из XSLT

Я пытаюсь вызвать статический метод Java из моей таблицы стилей XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                              xmlns:digest="java:org.apache.commons.codec.digest.DigestUtils">
<xsl:output method="xml" encoding="utf-8" indent="yes"/>

<xsl:template match="user">
  <user>
    <firstname>
      <xsl:value-of select="value[@type='firstname'][1]" />
    </firstname>
    <lastname>
      <xsl:value-of select="value[@type='name'][1]" />
    </lastname>
    <password>
      <xsl:variable name="password" select="string(value[@type='password'][1])" />
      <xsl:value-of select="digest:md5Hex($password)"
                    disable-output-escaping="yes" />
    </password>
  </user>
</xsl:template>

Найден класс DigestUtils и статический md5Hex-метод [1]. Проблема в том, что есть три возможных способа вызвать метод, а именно с помощью byte [], InputStream или String. Учитывая, что переменная «пароль» имеет тип xs: string, я предположил, что Saxon автоматически выберет последний вариант. Но вместо этого он настаивает на методе byte [] и соответственно терпит неудачу:

[...]
Loading org.apache.commons.codec.digest.DigestUtils
Looking for method md5Hex in Java class class org.apache.commons.codec.digest.DigestUtils
Number of actual arguments = 1
[...]
Trying method md5Hex: name matches
Method is static
Method has 1 argument; expecting 1
Found a candidate method:
    public static java.lang.String org.apache.commons.codec.digest.DigestUtils.md5Hex(byte[])
Trying method md5Hex: name matches
Method is static
Method has 1 argument; expecting 1
Found a candidate method:
    public static java.lang.String org.apache.commons.codec.digest.DigestUtils.md5Hex(java.io.InputStream) throws java.io.IOException
Trying method md5Hex: name matches
Method is static
Method has 1 argument; expecting 1
Found a candidate method:
    public static java.lang.String org.apache.commons.codec.digest.DigestUtils.md5Hex(java.lang.String)
[...]
Finding best fit method for arguments
Trying option 0: public static java.lang.String org.apache.commons.codec.digest.DigestUtils.md5Hex(byte[])
Conversion preferences are [24]
Trying option 1: public static java.lang.String    org.apache.commons.codec.digest.DigestUtils.md5Hex(java.io.InputStream) throws java.io.IOException
Conversion preferences are [80]
Trying option 2: public static java.lang.String org.apache.commons.codec.digest.DigestUtils.md5Hex(java.lang.String)
Conversion preferences are [80]
Eliminating option 1
Eliminating option 2
Number of candidate methods remaining: 1
Error at xsl:template on line 14 column 30 of migrate_users.xsl:
  Cannot convert from xs:string to byte
Failed to compile stylesheet. 1 error detected.

Есть ли способ заставить Saxon использовать String-метод?

[1] http://commons.apache.org/codec/api-release/org/apache/commons/codec/digest/DigestUtils.html#md5Hex(java.lang.String)

- обновление: коллега только что нашел лицензионный ключ компании для Saxon 9.4PE. К сожалению, ошибка сохраняется, единственное, что изменилось, - это то, что предпочтение преобразования для метода byte [] изменилось с 24 на 31.


person jbaiter    schedule 12.07.2012    source источник


Ответы (2)


Вам нужно ввести свою переменную:

<xsl:variable as="xs:string" name="password" select="string(value[@type='password'][1])" />

или введите его в вызов:

<xsl:value-of select="digest:md5Hex(xs:string($password))"
                disable-output-escaping="yes" />

С пространством имен xs, определенным как:

xmlns:xs="http://www.w3.org/2001/XMLSchema"
person Barnaby Shearer    schedule 12.07.2012
comment
Спасибо, приведение переменной во время вызова помогло. Однако ввод переменной не помог. В любом случае, остается вопрос, почему это не сработало в первую очередь, поскольку Saxon явно получил аргумент xs: string (как видно из сообщения об ошибке). - person jbaiter; 12.07.2012

Saxon пытается решить, какой метод использовать во время компиляции, на основе статического анализа типа предоставленного аргумента. Если предполагаемый статический тип допускает последовательность (в отличие от синглтона), то метод, который ожидает массив или коллекцию, всегда будет иметь преимущество перед методом, ожидающим синглтон: поэтому тот факт, что метод, ожидающий byte [], был предпочтительным, означает, что Саксон не смог понять, что предоставленное значение было одноэлементным. Очевидно, что приведение к строке достаточно, чтобы сделать этот вывод.

К сожалению, недостаточно добавить информацию о типе в объявление переменной. Причина этого в том, что решение о том, какой метод использовать, принимается слишком рано в процессе компиляции, до того, как информация о типе будет распространена из объявления переменной в ссылку на переменную. Я рассмотрю возможность улучшения этого в будущем выпуске.

person Michael Kay    schedule 12.07.2012