Чтение онлайн

ЖАНРЫ

Технология XSLT

Валиков Алексей Н.

Шрифт:

Результатом этого преобразования будет следующий документ.

Листинг 10.7. Результирующий SVG-документ

<!DOCTYPE svg

 PUBLIC "-//W3C//DTD SVG 1.0//EN"

 "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">

<svg

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

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

 width="200"

 height="200">

 <desc>Simple line-based figure</desc>

<g style="stroke:black; stroke-width:2">

<line

x1="81.68060041188197" y1="31.70359014757173"

x2="168.29640985242827" y2="81.68060041188197"/>

<line

x1="168.29640985242827" y1="81.68060041188197"

x2="118.31939958811803" y2="168.29640985242827"/>

<line

x1="118.31939958811803" y1="168.29640985242827"

x2="31.70359014757173" y2="118.31939958811803"/>

<line

x1="31.70359014757173" y1="118.31939958811803"

x2="81.68060041188197" y2="31.70359014757173"/>

 </g>

</svg>

Визуальное

представление этого документа демонстрирует рис. 10.2, где представлен поворот, выполненный на 30°:

Рис. 10.2. Визуальное представление полученного SVG-документа

Анализируя полученный документ, мы можем заметить объявление пространства имен с префиксом

math
, которое было в него включено:

<svg

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

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

 width="200"

 height="200">

 ...

Это тот самый случай, когда объявление пространства имен используется в самом преобразовании, но является лишним в выходящем документе. Для того чтобы избавиться от него, нужно просто включить префикс

math
в атрибут
exclude-result-prefixes
элемента
xsl:stylesheet
.

<xsl:stylesheet

 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
— если нет.

Поделиться с друзьями: