Главная » XSLT » Избегайте подводных камней при переносе с XSLT 1.0 на 2.0

0

Задача

Не каждая таблица стилей, созданная для версии 1.0, будет без изменений ра­ботать и в 2.0.

Решение

При переносе таблиц стилей из версии 1.0 в 2.0 нужно помнить о нескольких подводных камнях. Часть из них можно обойти, включив режим совместимости с XSLT 1.0; для этого нужно задать атрибут version="1.0" в элементе stylesheet: <xsl: stylesheet version= " 1. 0 " >. Но уж раз вы начали перенос старых программ в версию 2.0, то есть и другие способы справиться с несовместимостями.

Процессоры XSLT 2.0 не обязаны поддерживать режим обратной совме­стимости, хотя большинство все-таки поддерживает. Если это не так, про­цессор известит об ошибке.

Последовательности не преобразуются неявно в атомарные значения

Рассмотрим такой фрагмент: <xs l: value-of select= " substr ing- before(Name, ‘ ‘)"/>. Что произойдет, если он вычисляется в контексте, где есть более одного элемента Name? В XSLT 1.0 используется только первый элемент, а остальные игнорируются. Но XSLT 2.0 в этом отношении ведет себя строже и из­вещает об ошибке типизации, так как первый аргумент функции substring- before должен быть последовательностью, содержащей 0 или 1 строку.

Чтобы не сталкиваться с такой ошибкой, возьмите за правило писать <xsl:value-of select="substring-before(Name[1], ‘ ‘)"/>. С другой стороны, иногда полезно получать извещение об этой ситуации, поскольку она может свидетельствовать о наличии ошибки в таблице стилей или входном документе. Аль­тернативное решение заключается в том, чтобы объединить несколько узлов в один перед тем, как подавать последовательность на вход функции, ожидающей един­ственный узел. Например, если написать <xsl:value-of-select="substring- before(string-join(Name), ‘ ‘)"/>, то ошибки не возникнет.

Типы не преобразуются неявно в другие типы

В XSLT 1.0 допускается большая свобода во всем, что касалось преобразова­ний типов. Если функция ожидает число, а вы передали ей строку, то она сделает все возможное, чтобы преобразовать строку в число или наоборот. То же справед­ливо в отношении булевского значения и целого числа или строки и булевского значения. Старое поведение можно сохранить, установив режим совместимости с версией 1.0. Но можно также преобразовывать типы явно:

<xsl:variable name="a" select=" ’10’ "/> <xsl:value-of select="sum($a, 1)"/> <!– Ошибка –> <xsl:value-of select="sum(number($a), 1)"/> <!— Правильно —>

<xsl:value-of select="string-length(10)"/> <!– Ошибка –> <xsl:value-of select="string-length(string(10))"/> <!– Правильно –> <xsl:value-of select="string-length(string(true()))"/>

<!– Правильно, равно 4 –>

<xsl:value-of select="1 + true()"/> <!– Ошибка –>

<xsl:value-of select="1 + number(true())"/> <!– Правильно, равно 2 –>

Лишние параметры не игнорируются

В XSLT 1.0, если шаблону, вызываемому командой xsl:call-template, пе­редавались параметры, которые в шаблоне не были определены, то они просто игнорировались. В версии 2.0 это считается ошибкой. Подавить такую ошибку можно, включив режим совместимости. Никаких других обходных путей не су­ществует, можно лишь удалить лишние параметры или определить в существую­щем шаблоне значения параметров по умолчанию.

Более строгий контроль семантики приводит к ошибкам в сомнительных случаях

Это можно наблюдать на примере команд xsl:number и xsl:template. Если в xsl:number одновременно заданы атрибуты level и value, то в XSLT 1.0 level игнорируется, а в 2.0 это ошибка. Аналогично, в команде xsl:template в версии 2.0 запрещено указывать атрибут priority или mode, если отсутствует атрибут match.

Обсуждение

Включение режима совместимости для исправления ошибок в таблицах стилей, со­ставленных для версии 1.0, имеет и другие последствия. В частности, в некоторых отно­шениях программа начинает вести себя по-другому. Точнее, в режиме совместимости:

•                команда xsl:value-of возвращает только первый элемент последова­тельности, а не все элементы, разделенные пробелами;

•                выражение, употребленное в качестве значения атрибута (например, <foo values="{foo}"/>), выводит только первый элемент последовательности, а не все элементы, разделенные пробелами;

• при использовании команды xsl:number выводится только первое число,

а не все числа, разделенные пробелами; Поэтому вряд ли разумно полагаться на режим совместимости при разработке новых таблиц стилей, ориентированных на процессоры для XSLT 2.0.

Мангано Сэл  XSLT. Сборник рецептов. – М.: ДМК Пресс, СПБ.: БХВ-Петербург, 2008. – 864 с.: ил.

По теме:

  • Комментарии