このアーカイブは同期化されません。 mixi の日記が更新されても、このアーカイブには反映されません。
いよいよ、テンプレートを書いてみよう。
RSS 2.0 からの変換を行うので、
<channel> と <item> に着目してルールを書くことにする。
元の XML は以下の通り。
http://loafer.jp/mixi/diary/rss.xsp
========== simple.xsl ==========
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
<xsl:output
method="html"
doctype-public="-//W3C//DTD HTML 4.01 Transitional//EN"
doctype-system="http://www.w3.org/TR/html4/loose.dtd"
/>
<xsl:template match="channel">
<html>
<head>
<title>
<xsl:value-of select="title" />
</title>
</head>
<body>
<h1>
<a href="{link}">
<xsl:value-of select="title" />
</a>
</h1>
<p>
更新日: <xsl:value-of select="pubDate" />
</p>
<xsl:apply-templates select="item" />
<hr />
<address>
<xsl:value-of select="copyright" />
</address>
</body>
</html>
</xsl:template>
<xsl:template match="item">
<hr />
<h2>
<a href="{link}">
<xsl:value-of select="title" />
</a>
</h2>
<p>
<xsl:value-of select="description" />...<br />
(<small><xsl:value-of select="pubDate" /></small>)
</p>
</xsl:template>
</xsl:stylesheet>
========== end of simple.xsl ==========
定義するのは 2 つのテンプレートだけだ。
さて、XSLT の処理を順に考えていこう。
最初にルートノードがカレントノードに選択されて開始する。
ルートノードに対するテンプレートは定義していないため、
既定のテンプレートによって処理されることになる。
ルートノードや要素の既定テンプレートは
<xsl:apply-templates /> のみなので、
子ノードが順にカレントノードとなって処理される。
ここでは、rss 要素がそれに該当する。
rss 要素もテンプレートが定義されていないので、
上と同様、channel 要素に処理が移る。
channel 要素にはテンプレートが定義されているため、
<xsl:template match="channel"> で処理される。
このテンプレートには HTML の要素が含まれるので、
channel 要素はこれらに変換されて出力される。
<title>~</title> の内容としては、
<xsl:value-of select="title" /> と指定している。
XSLT の value-of 要素は、指定した値を文字列化する。
select 属性は XPath 式であり、"title" は
カレントノード(channel 要素)の直接の子供である
title 要素全てを選択したことになる。
これを value-of で文字列化すると、
該当ノードが複数ある場合でも、最初のノードだけが選ばれ、
その要素の子孫のテキストノードを全て連結した内容となる。
言い換えれば、最初に見つかった title 要素の内容から、
タグやコメント等を全て取り除いたものということだ。
次に出てくるのは、<a href="{link}"> だ。
これは、カレントノードの子の link 要素が文字列化され、
a 要素の href 属性の値として出力される。
XSLT では、属性に対して特別な処理を行う。
中括弧 {} で囲んだ内容は XPath 式として評価され、
その結果を文字列化したものに展開されるのだ。
このお陰で、属性値の出力も簡単に行うことができる。
その後には、<xsl:value-of select="title" /> が
再度出現するが、ここでも titie 要素が文字列化される。
基本的に value-of はそれぞれ独立して処理されるため、
必要であれば、何度でも同じ要素を選択することができる。
更新日: <xsl:value-of select="pubDate" /> や、
後ろにある <xsl:value-of select="copyright" /> も、
基本的には同じような方法で展開される。
そして、<xsl:apply-templates select="item" /> だ。
apply-templates は、子ノード全てに対して、
処理を継続(伝播)する命令だが、
select 属性で XPath 式を指定した場合、
それらで示されたノードだけ処理することが可能だ。
select="item" とあるため、
直接の子の全ての item 要素だけが処理されることになる。
ここでもし select 属性を省略した場合、
item 以外の要素などにもテンプレート処理が及んでしまう。
現在のカレントノードは、channel 要素である。
channel 要素は、item だけでなく、
pubDate、link、copyright などの要素も持つ。
link や pubDate は別の部分で使っており、
それら子要素を、この場所に展開する必要はないので、
select 属性を明示して処理させないのである。
つまり、このテンプレートの場合、
channel 属性の子供である language 属性は、
value-of 等で利用もされず、
apply-templates で選択されることもないため、
完全に無視されることになる。
さて、apply-templates は、item 要素を順に選択し、
それぞれをカレントノードとしてノード処理を行い、
その結果をこの部分に展開して出力する。
item 要素にはテンプレートが定義されているため、
各 item 要素は、<xsl:template match="item">
に従って処理されることになる。
item 要素用のテンプレートには目新しいところはない。
<a href="{link}"> や、
<xsl:value-of select="title" /> は上と同じだ。
カレントノードは item 要素なので、
これらは、item 要素の直接の子要素である、
link や title のことを指す。
item 要素のテンプレートには、
apply-templates 要素が含まれないため、
value-of などで利用している物を除き、
item 要素の子孫要素はノード変換されないことになる。
item 要素のノード処理内容は、それを呼び出した
channel 要素の apply-templates の場所に出力され、
channel 要素のテンプレート処理に戻ることになる。
上記の XSLT を反映するとこういう風になる。
http://loafer.jp/mixi/diary/rss.xsp?simple.xsl
単純なレイアウトではあるが、
XML の状態よりははるかに見やすくなった。
ソースを表示しても、元の XML のままだが、
レイアウト上は、HTML っぽいのは明らかだ。
つまり、XSLT によって HTML に変換されているのである。