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

ЖАНРЫ

Технология XSLT

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

Шрифт:

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

Листинг 10.5. Выходящий 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" width="200" height="200">

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

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

<line x1="50" y1="50" x2="150" y2="50"/>

<line x1="150" y1="50" x2="150" y2="150"/>

<line x1="150" y1="150" x2="50" y2="150"/>

<line x1="50" y1="150" x2="50" y2="50"/>

 </g>

</svg>

На

рис. 10.1 приведен пример визуального представления этого документа.

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

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

Формулы преобразования координат при повороте чрезвычайно просты:

x = x'∙cos(α) − y∙sin(α),

у = x'∙sin(α) + x'∙cos(α),

где x' и y' — старые координаты точки, x и y — новые координаты точки, а α — угол поворота. Единственная загвоздка состоит в том, что функций

sin
и
cos
в базовой библиотеке XPath нет.

Самым простым выходом в такой ситуации является использование расширений. Например, в случае XSLT-процессора, который может использовать Java-расширения (Saxon, Xalan, Oracle XSLT Processor и так далее) надо будет лишь только объявить пространство имен вида:

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

и использовать функции

math:sin
и
math:cos
.

Листинг 10.6. Преобразование, осуществляющее поворот

<?xml version="1.0" encoding="windows-1251"?>

<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">

 <xsl:output

indent="yes"

doctype-public="-//W3C//DTD SVG 1.0//EN"

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

 <xsl:param name="alpha" select="30"/>

 <xsl:variable name="alpha-radian" select="3.14 * ($alpha div 180)"/>

 <xsl:template match="/">

<svg width="200" height="200">

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

<xsl:apply-templates select="точки"/>

</svg>

 </xsl:template>

 <xsl:template match="точки">

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

<xsl:apply-templates select="точка"/>

</g>

 </xsl:template>

 <xsl:template match="точка">

<xsl:variable name="x1" select="@x"/>

<xsl:variable name="y1" select="@y"/>

<xsl:variable name="x2r">

<xsl:choose>

<xsl:when test="position = last">

<xsl:value-of select="preceding-sibling::точка[last]/@x"/>

</xsl:when>

<xsl:otherwise>

<xsl:value-of select="following-sibling::точка[1]/@x"/>

</xsl:otherwise>

</xsl:choose>

</xsl:variable>

<xsl:variable name="y2r">

<xsl:choose>

<xsl:when test="position = last">

<xsl:value-of select="preceding-sibling::точка[last]/@y"/>

</xsl:when>

<xsl:otherwise>

<xsl:value-of select="following-sibling::точка[1]/@y"/>

</xsl:otherwise>

</xsl:choose>

</xsl:variable>

<xsl:variable name="x2" select="number($x2r)"/>

<xsl:variable name="y2" select="number($y2r)"/>

<line

x1="{$x1 * math:cos($alpha-radian) -

$y1 * math:sin($alpha-radian) + 100}"

y1="{$x1 * math:sin($alpha-radian) +

$y1 * math:cos($alpha-radian) + 100}"

x2="{$x2 * math:cos($alpha-radian) -

$y2 * math:sin($alpha-radian) + 100}"

y2="{$x2 * math:sin($alpha-radian) +

$y2 * math:cos($alpha-radian) + 100}"/>

 </xsl:template>

</xsl:stylesheet>

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