●XHTMLを書く
XMLからXSLT変換を行ってHTML文書を生成させるためには、
XSLTスタイルシートにはHTML文書を一歩厳格にした「XHTML」
の体裁で書かなくてはいけません。
これはそんなにムズカシイことではないのですが、
ついついうっかり間違えてしまいがちなので、ここで超基本をまとめておきます。
●リンクの半角波線(チルダ)がXSLTを行うと文字化け
リンクの半角波線は%7eとエスケープします。
●XMLとXSLのテンプレート
<?xml version="1.0" encoding="Shift_JIS"?>
<?xml-stylesheet type="text/xsl" href="oramemo.xsl" ?>
<document>
...
</document>
|
<?xml version="1.0" encoding="Shift_JIS"?>
<!-- <xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl"> -->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="html" encoding="Shift_JIS" version="1.0"
doctype-public="-//W3C/DTD XHTML 1.0 Strict/EN"
doctype-system="DTD/xhtml1-strict.dtd" />
<xsl:template match="/document">
...
</xsl:template>
<xsl:stylesheet>
|
●HTMLタグの属性にXMLの値を使うには
XLSTで、XMLタグの値をA HREF=タグの値に使いたいときは、
<a href="<xsl:value-of select="url" />">リンク</a>
|
とすると、エラーになってしまいます。この場合の正解は
です。
●XSLTでの変数の使用
xsl:variableタグを使い、
XSL変数を定義します。{$変数名}という形で参照できます。
<xsl:variable name="url">
<xsl:value-of select="url" />
</xsl:variable>
<a href="{$url}">リンク</a>
|
●xsl:for-eachと番号づけ
xsl:for-eachタグで複数のエントリを表形式などに繰り返し処理するとき、
各行を1番から順に番号づけしたい場合、
xsl:numberタグを使います。
下の例のように、2種類の使い方があります。
format=には、「(1)」「1. 」「1」のような感じで書式を指定します。
<xsl:for-each select="customer">
<tr>
<td bgcolor="#e0ccdc">
<!-- <xsl:number value="position()" format="1. "/> -->
<xsl:number level="single" count="customer" format="1. " />
</td>
<td><xsl:value-of select="name" /></td>
<td bgcolor="#e0ccdc"><xsl:value-of select="address" /></td>
</tr>
</xsl:for-each>
|
●HTMLタグを含む文章をXMLに埋め込む
よくある例ですが、日記の本文のようなXML要素の中で、
改行などのためにHTMLタグを使ったとき、
そのHTMLタグも含めてXLSTでHTML文書に変換したい、
ということがあります。この場合は、そのXML要素をvalue-ofの代わりに
copy-ofで参照すればOKです。以下はXSLスタイルシートの一部です。
<xsl:template match="entry">
<p><xsl:copy-of select="description" /></p>
</xsl:template>
|
これで、*/entry/descriptionという要素がHTMLタグを含む文章である場合、
その内容がHTML構造も含めてpタグの間に挿入されます。
●テンプレートにパラメータを渡す
テンプレートを呼び出すとき、パラメータを一緒に渡して、
それによってテンプレートの処理を変えたりすることができます。
テンプレート側でパラメータを定義するには、xsl:param タグを使います。
<xsl:template name="example">
<xsl:param name="dumparam"/>
...
<xsl:if test="$dumparam = ''">
...
</xsl:if>
</xsl:template>
|
初期値(デフォルト値)も設定できます。これは、
テンプレートがパラメータを渡されずに呼ばれたときに使われる値です。
<xsl:template name="example">
<xsl:param name="dumparam">99</xsl:param>
...
<xsl:if test="$dumparam = ''">
...
</xsl:if>
</xsl:template>
|
呼び出す側は、xsl:call-templateタグの中に、
xsl:with-paramタグをパラメータの数だけ列挙します。
<xsl:call-template name="example">
<xsl:with-param name="dumparam">10</xsl:with-param>
</xsl:call-template>
|
●XSLに外部からパラメータを渡す
あるXSLを適用する際に、XSLT実行を指示するアプリケーション側から、
何かパラメータを渡してやって、それで動作を制御することもできます。
<xsl:param name="targetStr" select="aaa" />
<xsl:template match="/document/file">
<xsl:for-each select="$doc//document/category/entry">
<xsl:if test="contains(qq, $targetStr) or contains(aa, $targetStr)">
(後略)
|
これも上記と同様xsl:paramを使います。
ただし、そのタグの位置が違っていて、どのxsl:template等にも囲まれていない、
最上位に書く必要があります。
パラメータが渡されると、後はどのテンプレート内でも、「$パラメータ名」
の形で自由に参照することができます。
パラメータの渡し方は、外部アプリケーション次第です。
例えばlibXSLTに含まれるコマンドラインXSLTプロセッサ、xsltprocでは、
--paramオプションで指定できます。
% xsltproc --param targetStr 'NEW_VALUE' abc.xml
|
パラメータの「値」はXPath式として解釈されるので、
文字列はシングルクォートで囲むのを忘れずに!とFAQに載っています。
またJavaのXSLTプロセッサであるApache Xalanには、
XSLにパラメータを設定するAPIが公開されています。
この例がとても実用的で、
分かりやすいと思います。
●テンプレートを別ファイルからインポートする
テンプレートを別ファイルから取り込む方法は、
テンプレートの再利用性という意味で大きな効果があります。
まず、インポート「される」別ファイルを次のように作ります。
<?xml version="1.0" encoding="euc-jp"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template name="example">
...
</xsl:template>
</xsl:stylesheet>
|
上記のファイルをsample.xslを名づけます。
今度はこのテンプレートをインポートするXSL文書です。
冒頭のxsl:stylesheetタグとxsl:outputタグの間に
<xsl:import href="./sample.xsl" />
|
と書くとテンプレートがインポートされます。
実際に使うには?もちろん、テンプレートを呼び出したい位置で
xsl:call-templateタグを使えばOKです。
なお、xsl:includeというタグも同じように外部ファイルを取り込みます。
こちらは、xsl:stylesheetタグの直下の階層に書きさえすれば、
XSL文書の冒頭部以外の場所にも記述できるという特徴があります。
それ以上の詳しいことは、まだ理解していません(-_-;)
●文書型定義(DTD)を書く
XML文書が想定しているタグ構造で本当に書かれているかどうかをXMLパーサがチェックするための仕組として、
文書型定義があります。
これはこんなものです。
<!ELEMENT document (title, last_updated, category*)>
<!ELEMENT category (ctitle, entry*)>
<!ELEMENT entry (id, class, qq, aa, keyword, entrydate)>
|
最もシンプルなサンプルですが、
これはELEMENTの右側の要素が、その中にどんな要素を含めることができるかを示したものです。
*は、その要素を複数含めることができることを指定します。
文書型定義を別のファイルにする場合、通常.dtdという拡張子をつけます。
一般のXML文書から参照する場合には、
<?xml version="1.0" encoding="euc-jp" ?>
<?xml-stylesheet type="text/xsl" href="../common/example.xsl" ?>
<!DOCTYPE document SYSTEM "example.dtd">
...
|
と、文書の冒頭部でDOCTYPE宣言で参照します。
●XSLスタイルシートの中にCSSを書く
CSSの中に含まれる特殊文字をXSLTプロセッサに解釈させないために、CDATAセクションを使います。
<head>
<title><xsl:value-of select="title" /></title>
<style type="text/css"><![CDATA[
div#title { color : #400000; background-color : #ffeeee ;
border : 2px solid; padding : 3px; width : 50%; }
a:link { text-decoration:none; color:#800000; }
a:visited { text-decoration:none; color:#400000; }
a:hover,a:active { text-decoration:none; color:#C00000; }
body { color : #000060; }
]]></style>
</head>
|
●1つの要素に対して、2種類以上のテンプレートをxsl:apply-templatesするには?
この方法は分かりません。今のところ、複数のうちどれか1つだけをxsl:apply-templatesで適用し、
残りはxsl:for-eachタグのループを使って実現しています。
●XSLTで を出力する方法
試すと分かりますが、出力HTMLに「 」を出力させようとすると、
XSLに「 」や「&nbsp;」と書いてもうまくいきません。正解は
<xsl:text disable-output-escaping="yes">&nbsp;</xsl:text>
|
です。
(first uploaded 2002/01/13 last updated 2006/08/06, URANO398)
|