2013-06-22 2 views
0

Я обновил версию SaxonB (процессор XSLT 2.0) с 9.0 до 9.1.0.8, и моя программа (XML Web Generator) перестала работать.SaxonB 9.0 vs. SaxonB 9.1.0.8 и xs: boolean vs. xs: ошибка типа строки

Преобразование XSLT выполняется с использованием Ant. И Saxon Теперь жалуется:

[xslt] .../stránka.xsl:37: Fatal Error! Required type is xs:boolean; supplied value has type xs:string 
[xslt] Failed to process null 

Но на строке 37 этого XSLT-файла есть:

<xsl:include href="stránka-společné.xsl"/> 

и это, вероятно, не проблема. Это может быть на линии 47, где я использую свойство (набор из Ant) в < XSL: если тест = "$ SomeProperty"/>

Свойство объявлен в включенной XSL файл:

<xsl:param name="someProperty" select="false()" as="xs:boolean"/> 

I используйте символы Unicode в имени свойства, но он должен работать, не так ли? (по крайней мере, он работал в 9.0). Я попытался использовать ASCII, и это не помогло.

Это также не версия Ant или Java, потому что независимо от того, работает она или нет, это зависит только от пути к файлу JAR (9.0 по сравнению с 9.1.0.8).

Я хотел был бы сделать приложение совместимым с 9.1.0.8. (Или это ошибка в SaxonB?)

Версии Я использовал (SHA-256):

3cb7336b154eabfb0d78a1b9b5f7c70e15a9c790193676803fa4391b60de7ebb saxonb-9.0.jar (working) 
dc09c0e3d03609ff3c11b1e19446ca82a5f7f1bc364173b7910f2267312bd7d5 saxonb-9.1.0.8.jar (error described above) 

Файлы могут быть найдены, например, на package.ubuntu.com внутри .deb файлов - пакет libsaxonb-java в lucid (9.0) или raring (9.1.0.8).

Update # 1

Если удалить использования этого проблемного свойства (переменные в XSLT) я получил другую ошибку:

[xslt] Failed to process null 

BUILD FAILED 
…/build.xml:39: ; SystemID: file:…/šablona/makra/diagramy.xsl; Line#: 63; Column#: -1 
net.sf.saxon.instruct.TerminationException: Processing terminated by xsl:message at line 89 in diagramy.xsl 
    at net.sf.saxon.instruct.Message.processLeavingTail(Unknown Source) 
    at net.sf.saxon.instruct.Choose.processLeavingTail(Unknown Source) 
    at net.sf.saxon.expr.LetExpression.processLeavingTail(Unknown Source) 
    … 

Что также специфично для версии 9.1.0.8 (с 9.0 У меня нет ошибки). В строке 63 в diagramy.xsl есть:

<xsl:variable name="souborDiagramu" select="j:vytvořDiagram(
    $zadání, 
    @orientace = 'vodorovně', 
    $kompletní, 
    tokenize(base-uri(), '/')[last()], 
    @src 
    )"/> 

Где @orientace и @src отсутствуют в исходном документе (в 9,0 такие атрибуты были переданы методу Java vytvořDiagram(…) как null аргументы).

Update # 2

Я написал функцию в Java, чтобы получить тип недвижимости:

public static String zjistiTyp(Object o) { 
    if (o == null) { 
     return "null"; 
    } else { 
     return o.getClass().getName(); 
    } 
} 

С версии 9.0 это

<xsl:message>Typ proměnné $podporaZaostalýchProhlížečů = <xsl:value-of select="j:zjistiTyp($podporaZaostalýchProhlížečů)"/></xsl:message> 

успешно печатает:

[xslt] Typ proměnné $podporaZaostalýchProhlížečů = java.lang.Boolean 

Но с 9.1.0.8 Я получил ошибку Required type is xs:boolean; supplied value has type xs:string, даже если я удалил любые другие препятствия (использование этого свойства), и преобразование продолжается, если я удалю его последнее использование: <xsl:message>Typ proměnné… (но тогда я не могу узнать тип свойства).

Так что, похоже, что строка false (или true) может передаваться от Ant в XSLT и даже Собственость могут быть объявлены в XSLT, используя эту конструкцию:

<xsl:param name="podporaZaostalýchProhlížečů" select="false()" as="xs:boolean"/> 

, но он не может быть использован - использование такого свойства вызывает ошибку (но только в 9.1.0.8 - в 9.0 оно работает).

Update # 3

Я нашел обходной путь для одной части проблемы.

<xsl:param name="someParameterUncasted"/> 
<xsl:variable name="someParameter" select="$someParameterUncasted cast as xs:boolean"/> 

Но это уродливо, потому что мне нужны два имени для одного параметра - разные в Ant и разные в XSLT. Есть ли способ передать Boolean-типизированный параметр из Ant в XSLT? Почему это перестало работать в Saxon 9.1.0.8, хотя оно работало в 9.0?

И есть также вторая часть проблемы 9.0/9.1.0.8: при передаче значения некоторого отсутствующего атрибута в метод Java, в 9.0 он работал, и Java просто получил значение null. В 9.1.0.8 это приводит к ошибке.

+0

Скорее всего, Саксон жалуется на что-то в stránka-společné.xsl (и отмечая, что он был вызван в строке 37 stránka.xsl), чем это было бы думать, что это было в строке 37, когда оно было фактически на линии 47. Что находится в модуле stránka-společné.xsl? –

+0

Thanks; Я не нашел соответствующие файлы на package.ubuntu.com, но ваш репозиторий был легче ориентироваться. Как вы передаете значение параметра 'podporaZaostalýchProhlížečů' из Ant? Я предполагаю, что некоторые аспекты интерфейса Ant изменились в Saxon 9.1 (сайт Saxonica говорит, что 9.1 больше не включает в себя пользовательскую задачу Ant для Saxon). –

+0

Вы можете увидеть полный исходный код в моем [ртутном репозитории] (http://hg.frantovo.cz/xml-web-generator/file/c1999d6bc76a/%C5%A1ablona), если хотите :-) В 'stránka-společné ,xsl' в вопросе упоминается параметр. Если я удалю IF в 'stránka.xsl', который использует свойство, он продолжает и сбой где-то в другом месте (см. Обновление № 1). – Franta

ответ

1

[Не полный ответ, но, вероятно, слишком много, чтобы соответствовать удобно в комментарии.]

Ваши трудности возникают (возможно, правильно) к центру вокруг Ant/XSLT и интерфейсы XSLT/Java. Я бы попробовал несколько экспериментов.

  1. Попробуйте вызов от Ant, что делает не установить параметр podporaZaostalýchProhlížečů (и восстановить код, который проверяет значение этого параметра). Я предсказываю, что у вас не будет ошибки, о которой вы сообщили.
  2. Для целей тестирования измените значение по умолчанию параметра на значение true (используя объявление select="true()" в объявлении параметра). Я снова предсказываю, что первоначально заявленная ошибка не возникнет.
  3. Используйте простую таблицу стилей по линиям, показанным ниже, чтобы увидеть, что происходит в 9.0 и 9.1, когда Ant задает параметр testparm различными способами (в том числе, в частности, тем, как вы его устанавливаете сейчас). Отрегулируйте диагностику в соответствии с требованиями и попробуйте с помощью и без as="xs:boolean" в объявлении testparm. Если я правильно понял ситуацию, я ожидаю, что при запуске таблицы стилей тестов с сообщением Ant, говорящим <param name="testparm" expression="false"/>, Saxon 9.0 скажет вам, что testparm является логическим, а 9.1 скажет вам, что строка «false» не может быть переведена на логическое значение.

Первые два эксперимента должны подтвердить, что мир не ведет себя произвольным и капризным способом (мне всегда нравится проверять это при отладке) и что ваш код имеет смысл. Третий эксперимент, если он будет успешным, изолирует изменение поведения для входящих параметров и позволит вам экспериментировать с различными способами установки параметра из Ant. (Тем не менее, он ничего не поможет в вопросах интерфейса XSLT-to-Java, с которыми вы сталкиваетесь при вызове функции.)

Надеюсь, это поможет.

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    version="2.0"> 

    <xsl:param name="testparm" as="xs:boolean"/> 

    <xsl:template match="/"> 
    <xsl:choose> 
     <xsl:when test="$testparm instance of xs:boolean"> 
     <xsl:message>Test parameter <xsl:value-of 
      select="$testparm"/> is boolean.</xsl:message> 
     </xsl:when> 
     <xsl:when test="$testparm instance of xs:string"> 
     <xsl:message>Test parameter <xsl:value-of 
      select="$testparm"/> is a string.</xsl:message> 
     </xsl:when> 
     <xsl:when test="$testparm instance of xs:decimal"> 
     <xsl:message>Test parameter <xsl:value-of 
      select="$testparm"/> is decimal.</xsl:message> 
     </xsl:when> 
     <xsl:when test="$testparm instance of xs:anyAtomicType"> 
     <xsl:message>Test parameter <xsl:value-of 
      select="$testparm"/> is of type anyAtomicType.</xsl:message> 
     </xsl:when> 
     <xsl:when test="$testparm instance of xs:untypedAtomic"> 
     <xsl:message>Test parameter <xsl:value-of 
      select="$testparm"/> is untypedAtomic.</xsl:message> 
     </xsl:when> 
    </xsl:choose> 
    </xsl:template> 

</xsl:stylesheet> 

Преимущество делать этот тест в XSLT, а не в Java является то, что только интерфейс/XSLT Ant участвует, а не XSLT-вызова-Java интерфейс, а также.

Если невозможно найти способ передачи параметра из Ant, который успешно завершит логическое значение в 9.0 и 9.1, вы можете изменить тип параметра на строку: многие программисты XSLT живут долго и продуктивно использует значения «да» и «нет» вместо true() и false() и записывает свои тесты как test="$parm = 'yes'". К лучшему или худшему, строки проходят через границы среды лучше, чем многие другие типы.

+0

Спасибо, я попробовал ваш шаблон, и результаты: ** 1) Без as = "xs: boolean" в объявлении параметра **: Обе версии Saxon print 'Test parameter true - это строка. ** ** 2) С as = xs: boolean "в объявлении параметра **: версия 9.0 печатает' Test parameter true is boolean.', а версия 9.1.0.8 терпит неудачу с 'Fatal Error! Требуемый тип: xs: boolean; заданное значение имеет тип xs: string'. См. Также Обновление # 3 – Franta

2

Я считаю, что Ant всегда передает значение параметра stylesheet в качестве строки. Саксон, конечно, не контролирует это. Из ваших доказательств (я не сделал археологию для подтверждения этого) Saxon 9.0 передал заданное значение требуемому типу параметра, тогда как текущие выпуски (предположительно начиная с 9.1) используют правила преобразования типов, используемые для вызова функции, которые слабее, чем литье.

Если вы хотите, чтобы ваша таблица стилей могла быть вызвана из максимально возможного множества сред, я бы рекомендовал определить параметры таблицы стилей, которые принимают строки. Мы сделали то же самое (также начиная с Saxon 9.1) для параметров конфигурации - опять же, Ant всегда передает их как строки, поэтому мы позаботились о том, чтобы все параметры конфигурации могли быть представлены в виде строки.

Это вполне нормально иметь два параметра, позволяющие пользователям выбор:

<xsl:param name="use-macros" as="xs:boolean" select="xs:boolean($use-macros-string)"/> 
<xsl:param name="use-macros-string" as="xs:string" select="'false'"/> 
+0

Спасибо. Я ответил в отдельном ответе. – Franta

+0

BTW: У меня все еще проблема при передаче отсутствующего атрибута (@src в редакторе № 1) из шаблона в функцию Java. – Franta

0

Saxon 9.0 cast the supplied value to the required type of the parameter, whereas current releases (presumably starting from 9.1) use the type conversion rules used for function calling, which are weaker than casting.

Я понимаю, что это не хорошо, чтобы полагаться на автоматическое преобразование, если оно не охватывается спецификацией.

If you want your stylesheet to be callable from the widest possible set of environments, I would recommend defining stylesheet parameters that accept strings.

В таком случае да, но моя программа действительно «основана на муравьях», так что это не повредит мне. BTW: например. xsltproc также поддерживает выражения XPath в параметрах.

It's quite OK to have two parameters allowing users a choice

Это работает, но ИМХО это только временное решение и коды шаблона XSLT не правильный слой, где тип отливка входных параметров должна быть сделана - для каждого параметра, в каждом шаблоне, снова и снова.

Я бы предпочел улучшить Ant для поддержки большего количества типов данных, чем текстовые строки. Любой желающий может следовать своей деятельности в

Bug 21525 - XSLT/[email protected] used as string instead of as expression as documented

Мой патч добавляет поддержку для этих типов: строка, логическое значение, INT, длинные, двойные, а также выражения XPath в параметрах XSLT.

Смежные вопросы