FC2ブログ

XSLTで戸惑ったこと

こんにちは。
Kamui Kentaroです。

前回のXMLマスターベーシック向けツールを記事にした時、XMLマスターベーシック学習時に少し混乱したことを思い出しました。

今回はそのことについて書き綴りたいと思います。

具体的には、XSLTにおける繰り返しについてです。
技術的な内容になりますので、XMLマスターベーシックを目指す人専用になってしまうかもしれません。

具体的な例で見たほうが早いと思いますので、早速、例を挙げます。

xsl:apply-templatesの動き(子要素blu-rayを指定した場合)
まず、対象のXMLファイルは、前回のXMLマスターベーシック向けツールで使った「ブルーレイ.xml」を使います。

XML構造は次の通りです。

XMLNotepad2.jpg

前回記事で使ったXSLTスタイルシート「ブルーレイ.xsl」を使い、XMLを変換した場合は、次の通りに、全データが変換表示されました。

XMLNotepad3.jpg 



xsl:apply-templatesの動き(親要素blu-raysを指定した場合)
では、ここで問題です。


【問題】
次のXSLTスタイルシート「ブルーレイ2.xsl」を使った場合、どのように変換されるでしょうか? 



<?xml version="1.0" encoding="Shift_JIS"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" encoding="Shift_JIS" />
<xsl:template match="/">
<html>
<head></head>
<body>
<xsl:text>これはテストです。</xsl:text>
<br/>
<xsl:value-of select="blu-rays/@list_title" />
<table border="1">
<tr><th>タイトル名</th><th>主人公</th></tr>
<xsl:apply-templates select="blu-rays" />
</table>
</body>
</html>
</xsl:template>
<xsl:template match="blu-rays">
<tr>
<td><xsl:value-of select="blu-ray/title" /></td>
<td><xsl:value-of select="blu-ray/mainchar" /></td>
</tr>
</xsl:template>
</xsl:stylesheet>





:

:

:

:

:

:

:

:

:

:

:

【解答】
正解は、次の通りで、XMLファイル内に定義されている先頭のblu-rayタグの情報のみ表示されます。

XMLNotepad4.jpg

ポイントは、テンプレート呼び出し部分で、次の通りにXMLトップレベルの「blu-rays]を指定していること。
<xsl:apply-templates select="blu-rays" />

blu-raysaタグは、XMLファイル内には1つしか定義されていませんので、1回しか処理されません。
ですので、blu-raysnの子タグとして、3つあるblu-rayタグについては、先頭レコードのみが処理されます。
結果として、1行しか表示されません。

一方、XSLTスタイルシート「ブルーレイ.xsl」では、次の通り、blu-raysタグの子タグである「blu-ray」を指定しています。
<apply-templates select="blu-rays/blu-ray" />

blu-raysaタグは、XMLファイル内に、3つ定義されています
ですので、XMLファイルに定義されている3つのblu-rayタグが全て処理され、3行が表示されます。

3つのblu-rayタグ全てを処理する方法
では、現状通りに「blu-rays]を指定した状態はどうすれば、3行表示されるのか。
それは簡単です。

テンプレート側で、xsl:for-eachタグを使い、blu-rayタグを繰り返し処理してしまえばいいのです。
具体的なXSLTスタイルシートは、次の通りです。


<?xml version="1.0" encoding="Shift_JIS"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" encoding="Shift_JIS" />
<xsl:template match="/">
<html>
<head></head>
<body>
<xsl:text>これはテストです。</xsl:text>
<br/>
<xsl:value-of select="blu-rays/@list_title" />
<table border="1">
<tr><th>タイトル名</th><th>主人公</th></tr>
<xsl:apply-templates select="blu-rays" />

</table>
</body>
</html>
</xsl:template>
<xsl:template match="blu-rays">
<xsl:for-each select="blu-ray" >
<tr>
<td><xsl:value-of select="title" /></td>
<td><xsl:value-of select="mainchar" /></td>
</tr>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>





実際にこのスタイルシートを使って変換を行うと正しく、次の通りに3行が表示されることが確認できます。

XMLNotepad5.jpg 

少し長くなりましたので整理しておきます。

xsl:apply-templatesタグは、select属性で指定したノード全てを繰り返して処理する

ということになります。


私自身は、xsl:apply-templatesタグのことを学習した時、繰り返されるのか?xsl:for-eachを使って、明確に繰り返し処理をする必要があるのか?の違いに困惑しました。

資格対策教科書には、xsl:apply-templatesタグの繰り返し処理について、それほど詳しくは書いていなかったように思います。

XMLマスターベーシックを目指す人に、この記事が少しでも参考になれば幸いです。






スポンサーサイト



プロフィール

Kamui Kentaro

Author:Kamui Kentaro
プロフィール詳細はコチラです。

メール
最新記事
カテゴリ
全記事表示リンク

全ての記事を表示する

月別アーカイブ
リンク
※相互リンク募集中!
ブログランキング
クリック、更新の励みになります

FC2Blog Ranking

最新コメント
最新トラックバック
FC2カウンター
あし@
検索フォーム
RSSリンクの表示
QRコード
QR