2009年12月4日金曜日

XSLT で再帰でグラデーション

こんな XML を読み込んで、
<?xml version="1.0" encoding="UTF-8"?>
<table size="10"/>

HTML の<table>要素で作られた矩形領域の縦横を、size属性で指定された数で分割して、下のような緑と青のグラデーションのテーブルを作るような XSLT を書いてみたいとする。左上 の色が rgb(0, 0, 0) で、右下が rgb(0, 255, 255)である 。
<table size="5"><table size="10">

HTML ソースはこんな感じになる。
<table cellspacing="0" cellpadding="0">
<tr>
<td style="width:16px;height:16px;background-color:rgb(0,0,0)"></td>
<td style="width:16px;height:16px;background-color:rgb(0,0,28)"></td>
・・・略
<td style="width:16px;height:16px;background-color:rgb(0,0,255)"></td>
・・・略
<td style="width:16px;height:16px;background-color:rgb(0,255,0)"></td>
・・・略
<td style="width:16px;height:16px;background-color:rgb(0,255,255)"></td>
</tr>
</table>

これを以下のような再帰を使って、やってみた。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output method="html" indent="no"/>
<xsl:strip-space elements="list"/>

<xsl:template match="/table">
<table cellspacing="0" cellpadding="0">
<xsl:call-template name="rows">
<xsl:with-param name="s" select="@size"/>
<xsl:with-param name="g" select="@size - 1"/>
</xsl:call-template>
</table>
</xsl:template>
<xsl:template name="rows">
<xsl:param name="s"/>
<xsl:param name="g"/>
<xsl:if test="0<$g">
<xsl:call-template name="rows">
<xsl:with-param name="s" select="@size"/>
<xsl:with-param name="g" select="$g - 1"/>
</xsl:call-template>
</xsl:if>
<tr>
<xsl:call-template name="cols">
<xsl:with-param name="s" select="$s"/>
<xsl:with-param name="g" select="$g"/>
<xsl:with-param name="b" select="$s - 1"/>
</xsl:call-template>
</tr>
</xsl:template>
<xsl:template name="cols">
<xsl:param name="s"/>
<xsl:param name="g"/>
<xsl:param name="b"/>
<xsl:if test="0<$b">
<xsl:call-template name="cols">
<xsl:with-param name="s" select="$s"/>
<xsl:with-param name="g" select="$g"/>
<xsl:with-param name="b" select="$b - 1"/>
</xsl:call-template>
</xsl:if>
<xsl:variable name="blue" select="floor(255 * $b div ($s - 1))"/>
<xsl:variable name="green" select="floor(255 * $g div ($s - 1))"/>
<xsl:variable name="size" select="floor(160 div $s)"/>
<td style="width:{$size}px;height:{$size}px;background-color:rgb(0,{$green},{$blue})"/>
</xsl:template>
</xsl:stylesheet>

これを Eclipse で実行して、生成された <table>をペーストしたものが、上のグラデーションのテーブル。

0 件のコメント:

コメントを投稿