version='1.0'

 xmlns:xsl='http://www.w3.org/1999/XSL/Transform'

 xmlns='http://www.w3.org/2000/svg'

 xmlns:math='java:java.lang.Math'

 exclude-result-prefixes='math'>

 ...

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

Листинг 10.8. Класс, вычисляющий координаты точки после поворота

package de.fzi.xslt;

public class rot {

 public static double X(double x, double y, double degree) {

  double radian = Math.PI * degree / 180;

  return x * Math.cos(radian) - y * Math.sin(radian);

 }

 public static double Y(double x, double y, double degree) {

  double radian = Math.PI * degree / 180;

  return x * Math.sin(radian) + y * Math.cos(radian);

 }

}

Для того чтобы использовать методы этого класса в качестве функций расширения, немного изменим объявления в элементе xsl:stylesheet:

<xsl:stylesheet

 version='1.0'

 xmlns:xsl='http://www.w3.org/1999/XSL/Transform'

 xmlns='http://www.w3.org/2000/svg'

 xmlns:rot='java:de.fzi.xslt.rot'

 exclude-result-prefixes='rot'>

Создание элемента line теперь может быть записано в виде:

<line

 x1='{rot:X($x1, $y1, $alpha) + 100}'

 y1='{rot:Y($x1, $y1, $alpha) + 100}'

 x2='{rot:X($x2, $y2, $alpha) + 100}'

 y2='{rot:Y($x2, $y2, $alpha) + 100}'/>

Как мы отмечали выше, интерфейсы использования функций расширения весьма различаются между разными процессорами даже в случае такого переносимого языка, как Java. Отличия могут быть и в форме вызовов функций, и в форме объявлений пространств имен. Например, в процессоре Saxon пространство имен для класса de.fzi.xslt.rot может быть объявлено как:

xmlns:rot='java:de.fzi.xslt.rot'

в Xalan — как:

xmlns:rot='xalan://de.fzi.xslt.rot'

в Oracle XSLT Processor — как:

xmlns:rot='http://www.oracle.com/XSL/Transform/java/de.fzi.xslt.rot'

При этом сами вызовы во всех трех случаях будут одинаковыми:

rot:X($x, $y, $angle)

для метода X или

rot:Y($x, $y, $angle)

для метода Y.

Функция function-available

При использовании функций расширения всегда есть вероятность того, что это расширение в силу каких-либо причин поддерживаться данным процессором не будет. Чаще всего это случается, во-первых, когда процессор просто физически не в состоянии вызвать эту функцию (например, процессор, написанный на C++, вряд ли будет содержать средства для выполнения Java-кода), во-вторых, когда расширение недоступно (например, процессор не в состоянии найти указанный Java-класс или динамическую библиотеку), и в-третьих, когда пространство имен объявлено неверно (например, с URI java:de.fzi.xslt.rot вместо xalan://de.fzi.xslt.rot). Результатом обращения к неподдерживаемому расширению будет, естественно, ошибка.

XSLT позволяет избежать подобного рода ошибок путем предварительной проверки наличия заданной функции расширения. Для этой цели служит стандартная функция function-available (от англ. function is available — функция доступна)

boolean function-available (string)

Функция function-available принимает на вход строку, представляющую имя функции и возвращает true, если эта функция может быть вызвана и false — если нет.

Строковый аргумент этой функции представляет расширенное имя функции, он должен соответствовать продукции QName, то есть иметь вид имя или префикс:имя. В первом случае function-available проверяет, реализована ли в данном процессоре стандартная функция с таким именем, например function-available('concat') скорее всего, возвратит true.

В случае, если аргумент function-available имеет вид префикс:имя, функция function- available проверяет доступность указанной функции расширения. Например, для того, чтобы проверить, может ли в данном контексте быть вызвана функция rot:X, необходимо вычислить выражение

function-available('rot:X')

В данном случае true будет означать, что функция rot:X может быть вызвана, false — что функция в силу каких-то причин недоступна.

Функция function-available может помочь в создании преобразований, которые используют расширения, но при этом в некоторой степени сохраняют переносимость между различными процессорами. Достаточно написать несколько вариантов вызова функции расширения для каждого из процессоров, на которых преобразование должно работать, а затем использовать вариант с доступной данному процессору функцией расширения.

Пример

Для того чтобы обеспечить работоспособность расширения, реализованного классом de.fzi.xslt.rot в наиболее распространенных XSLT-процессорах, написанных на Java (как-то: Saxon, Xalan и Oracle XSLT Processor), прежде всего необходимо объявить соответствующие пространства имен:

<xsl:stylesheet

 version='1.0'

Вы читаете Технология XSLT
Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату