Визуальное представление этого документа демонстрирует рис. 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 пространство имен для класса