XMLマスターポイントレッスン ~ ベーシック編 ~
第9回 XSLTスタイルシートの仕組みとXPath
インフォテリア認定教育センター 鈴木智也 SUZUKI, Tomoya
前回は、基本的なスタイルシートの記述法としてxsl:template要素やxsl:apply-templates命令について解説しました。今回は、スタイルシートにテンプレートルールをどのように適用するのかという仕組みやXPathの記述法の詳細を解説します。今回の内容を理解することで複数のテンプレートルールに分割した分かりやすいXSLTスタイルシートを作成できるようになりますので、前回解説した内容も復習しながら読み進めてください。
ノード選択とパターンマッチング
XSLTスタイルシートでは、xsl:applytemplates命令のselect属性によるノード選択と、xsl:template要素のmacth属性によるパターンマッチングによりテンプレートルールが適用されます。また、適用可能なテンプレートルールが複数存在した場合や、適用できるテンプレートルールが存在しない場合にどのように解決すべきかが仕様として定められています。
ノードの選択
xsl:apply-templates命令のselect属性では、XPathの記述によって[1]同名のノードが複数選択される場合と、[2]異なる名前で複数のノードが選択される場合とが考えられます。
[1]の例として、図1ではXPathで「カタログ/商品」を指定すると、カタログ要素の子要素として「XMLストラップ」を含む商品要素ノードと「XMLマウスパッド」を含む商品要素ノードの2つの商品要素ノードが選択されます。
[2]の例として、図2では「カタログ/商品/*」と指定すると、品名要素ノードと単価要素ノードが選択されます。「*」はすべての要素ノードを表わします。このように複数のノードが選択されたものを「ノードセット」と言います。
また、XML文書に存在しないノードにxsl:apply-templates命令とxsl:template要素が記述されていたとしても、ノードが存在せず選択されないため、テンプレートルールは適用されません。
テンプレートの適用
例として、LIST1のXML文書にLIST2のXSLTスタイルシートを適用した場合を考えてみましょう。
LIST1:XML文書(list1.xml)
1 <?xml version="1.0" encoding="Shift_JIS"?>
2 <?xml-stylesheet type="text/xsl" href="list2.xsl"?>
3 <営業報告書>
4 <ヘッダ>
5 <記入日>2006/09/09</記入日>
6 <物件名>ABCサービス株式会社</物件名>
7 <担当者>山田太郎</担当者>
8 </ヘッダ>
9 <本文>
10 <成果>
11 <品名>XMLデータベース</品名>
12 <単価単位="千円">1230</単価>
13 <数量>1</数量>
14 </成果>
15 <成果>
16 <品名>XMLエディタ</品名>
17 <単価単位="千円">15</単価>
18 <数量>10</数量>
19 </成果>
20 </本文>
21 </営業報告書>
(※行番号は解説の便宜上付けたもので、実際のコードには不要です。以下同)
LIST2:XSLTスタイルシート(list2.xsl)
1 <?xml version="1.0" encoding="Shift_JIS"?>
2 <xsl:stylesheet version="1.0"
3 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
4 <xsl:template match="/">
5 <html>
6 <body>
7 <h1>営業報告書</h1>
8 <xsl:apply-templates select="営業報告書/ヘッダ/*"/>
9 <xsl:apply-templates select="営業報告書/本文"/>
10 </body>
11 </html>
12 </xsl:template>
13 <xsl:template match="記入日">
14 ・記入日:<xsl:value-of select="." /><br/>
15 </xsl:template>
16 <xsl:template match="物件名">
17 ・物件名:<xsl:value-of select="." /><br/>
18 </xsl:template>
19 <xsl:template match="担当者">
20 ・担当者:<xsl:value-of select="." /><br/>
21 </xsl:template>
22 <xsl:template match="本文">
23 <table border="1" width="300">
24 <tr><th>品名</th><th>価格</th><th>数量</th></tr>
25 <xsl:apply-templates select="成果"/>
26 </table>
27 </xsl:template>
28 <xsl:template match="成果">
29 <tr>
30 <td><xsl:value-of select="品名" /></td>
31 <td align="right"><xsl:value-of select="単価" />
32 (<xsl:value-of select="単価/@単位" />)</td>
33 <td align="right"><xsl:value-of select="数量" /></td>
34 </tr>
35 </xsl:template>
36 </xsl:stylesheet>
xsl:apply-templates命令のselect属性でノードセットが選択された場合には、それぞれのノードに対して個別にテンプレートを適用します。LIST2の26行目のxsl:applytemplates命令によりLIST1の10行目と15行目の成果要素ノードが選択されます。LIST2の30行目のテンプレートルールがそれぞれの成果要素ノードに適用されます。
また、LIST2の8行目のxsl:apply-templates命令によりLIST1の5~7行目の記入日要素ノード、物件名要素ノード、担当者要素ノードが選択され、これらに対してLIST2の13行目、16行目、19行目のテンプレートルールが適用されます。
パターンマッチング
xsl:apply-templates命令のselect属性で選択されたノードセット内の個々のノードにどのテンプレートルールを適用するかは、ノードセット内のそれぞれのノードがxsl:template要素のmatch属性に指定されたパターンにマッチするかどうかにより判断されます。図3では2つの品名要素ノードが選択されますが、これらに対し「商品/品名」と「補足/品名」というパターンのテンプレートルールがあります。選択されたそれぞれのノードには、そのノードのパターンにマッチするテンプレートルールが適用されます。
テンプレートルールの競合解決
では、適用可能なテンプレートルールが複数あるときはどうなるでしょうか。ルールには優先度が設けられており(表1)、適用可能なテンプレートルールが複数存在する場合には、優先度の高いものが適用されます。つまり、より具体的に指定されているルールが採用されます。仕様では、「最も優先度の高いテンプレートルールが複数存在する場合には、エラーとするか最も後ろに書かれているテンプレートルールを適用する」となっています。一般的なXSLTプロセッサでも、処理を続けるために最も後ろに書かれているテンプレートルールを適用するように実装されています。
表1:テンプレートルールの競合解決
パターン例 | 優先度 |
「*」「@*」「text ()」など、具体的な名前が指定されていないもの | -0.5 |
「接頭辞:*」「@ 接頭辞:*」など、名前空間は指定されているが具体的な名前が指定されていないもの | -0.25 |
「商品」「@ 単位」など、要素名や属性名が具体的に指定されているもの | 0 |
「ヘッダ/担当者」「本文/成果/商品」「単価/@ 単位」など、階層の指定があるもの | 0.5 |
※最も高い優先度のテンプレートルールが複数存在する場合は、エラーとするかまたは最後に現われるテンプレートルールを選択する
また、テンプレートルールの優先度は、そのノードのみが指定されているか、階層が指定されているかの違いが影響します。例えば、「品名」(優先度0)と「商品/品名」(優先度0.5)では、「商品/品名」のほうが優先度は高くなりますが、「カタログ/商品/品名」と「商品/品名」はどちらも階層が指定されているので同じ優先度(0.5)となり、後に書かれたテンプレートルールが適用されます。
組み込みテンプレートルール
逆に、適用するテンプレートルールが存在しなかった場合はどうなるでしょうか。XSLTでは、このような場合でも変換できるように、あらかじめいくつかのテンプレートルールが用意されています。これを「組み込みテンプレートルール」と言います(図4)。
図4:組み込みテンプレートルール
[1]対応する要素ノード/ルートノードのパターンが存在しない場合はさらにその子ノードに対してテンプレートルールを適用させる
〈xsl:apply-templates/〉
〈/xsl:template〉
[2]対応するテキストノード/属性ノードのパターンが存在しない場合はそのノードの値を出力する
〈xsl:value-of select="."/〉
〈/xsl:tempate〉
[3]対応する処理命令ノード/コメントノードのパターンが存在しない場合は何もしない
[1]では、ルートノードとすべての要素ノードにテンプレートルールを適用します。このときカレントノードのすべての子ノードを選択し、それらに対してテンプレートルールを適用しようとします。この繰り返しにより順に子ノードをたどって行き、マッチするテンプレートルールを探そうとします。たどって行くと、テキストノードにたどり着く可能性があります。この場合には[2]が適用されその値が表示されます。
また、xsl:apply-templates命令のselect属性で、属性ノードが選択されたもののマッチするテンプレートルールが存在しなかった場合にも[2]が適用されます。処理命令ノードやコメントノードが選択され、マッチするテンプレートルールが存在しなかった場合には[3]が適用されます。
このように、変換を継続できるようにマッチするテンプレートルールが存在しなかった場合には順番に子ノードをたどって行き、テキストノードが出てきたらその文字列を出力していきます。
XPath の記述方法
ノードの選択やテンプレートルールのパターンではXPathを使って指定します。XPathをうまく指定することにより、より柔軟にスタイルシートを記述できるようになります。選択するノードをさらに絞り込んだり、階層をさかのぼって指定することもできます。XPathでは、単にノードの階層だけでなく、さまざまな指定が可能です。例えば、数値計算をしたり部分文字列を取り出したりできます。ここでは、XPathによるロケーションパスの記述方法やXPath関数について紹介します。
ロケーションパスとロケーションステップ
XPathではXMLのデータ構造をノードツリーによる階層構造と考え、特定の階層にあるノードを指定できます。この階層の経路を記述したものが「ロケーションパス」です。
ローションパスには、「絶対パス」と「相対パス」の2通りの表現方法があります。テンプレートルールにマッチしたノードがカレントノードとなり、そのカレントノードを起点として指定したいノードへの経路を記述したものを「相対パス」、ルートノードを起点として指定したいノードへの経路を記述したものを「絶対パス」と言います。
ロケーションパスは、その経路を「/」で区切って指定し、その区切られた部分を「ロケーションステップ」と言います。ロケーションステップは「軸」、「ノードテスト」、「述部」によって記述します(LIST3)。
LIST3:ロケーションパスとロケーションステップ
ロケーションパス=絶対パスまたは相対パス
絶対パス=/相対パス
相対パス=ロケーションステップ/ロケーションステップ...
ロケーションステップ=軸::ノードテスト[述部]
(記述例)
絶対パス:"/""/カタログ/商品"
相対パス:"カタログ/商品""商品""単価/@単位"
これまではノードテストのみを指定し、階層を順にたどって行くだけでしたが、軸を指定することにより階層をさかのぼったり、述部によってノードをフィルタリングしたりできます。
カレントノードとコンテキストノード
テンプレートルールを処理するときの基点となるノードを「カレントノード」と言います。XPathで相対パスによって表現する場合には、カレントノードを基点にして考えます。ロケーションパスの各ロケーションステップでのノードを「コンテキストノード」と言います。
軸
コンテキストノードから次のロケーションステップに対して相対的な位置関係を指定するために「軸」を指定できます(表2)。軸により、親ノードを指定したり同階層の前後のノードを指定することもできます。
表2:ロケーションステップの軸
軸名 | 意味 |
self | コンテキストノード |
parent | 親ノード |
ancestor | 祖先ノード |
ancestor-or-self | 祖先ノードとコンテキストノード |
child | 子ノード |
descendant | 子孫ノード |
descendant-or-self | 子孫ノードとコンテキストノード |
preceding-sibling | 自分より前の兄弟ノード |
preceding | 祖先と属性と名前空間を除くコンテキストより前のノード |
following-sibling | 自分より後ろの兄弟ノード |
following | 子孫と属性と名前空間を除くコンテキストより後ろのノード |
attribute | 属性ノード |
namespace | 名前空間ノード |
軸を省略した場合はchild軸を指定していることになります。これまでの例では軸を指定していなかったためchild軸、つまり子ノードが指定されていました。軸は「軸名::」と指定します。
軸の指定を簡略化した記号も用意されています(表3)。ほとんどの場合は簡略化した記号で表現できるので、表現できない特殊な場合のみ軸を指定します。
表3:軸の簡略化
簡略化の記号 | 軸 | 簡略化した表現 | 軸を使用した表現 |
軸の省略 | child:: | 商品/品名 | child::全国/child::情報 |
@ | attribute:: | 単価/@ 単位 | child::県名/attribute::読み |
// | /descendant-or-self::node()/ | //県花 | /descendant-or-self::node()/child::県花 |
. | self::node() | ./県名 | self::node()/child::県名 |
.. | parent::node() | ../県花 | parent::node()/child::県花 |
ノードテスト
ノード名を指定します(表4)。軸とノードテストにより、コンテキストノードに対する位置とノードを指定します。軸とノードテストは「軸名::ノード名」と記述します。
表4:ノードテスト
ノードテスト | 記述例 |
要素名 | 「商品」「ns:担当者」 |
すべての要素ノード | 「*」「ns:*」 |
あらゆるノード | node() |
テキストノード | text () |
コメントノード | comment() |
例えば、「parent::商品」と指定すれば、一階層上にある商品要素ノードを表わしていることになります。また、「descendant::品名」と指定すれば、子孫ノードにある品名要素ノードを表わしていることになります。
述部
述部には条件を記述し、ノードセットをフィルタリングできます。[]の中にXPath式を指定します。記述されるXPathは次のように分類できます。
- [1]ブール値(true/false)で表わされるもの
- [2]数値になるもの
- [3]ノードセットになるもの
- [4]文字列になるもの
[1]ブール値(true/false)で表わされる場合
trueとなるノードだけが選択されます。XPathには条件を記述するための関係演算子や論理演算子が用意されていますが(表5)、これによりブール値の結果を得ることができます。
表5:関係演算子と論理演算子
● 関係演算子記号 | 説明 |
= | 等しい |
!= | 等しくない |
< | より小さい(<と記述する) |
> | より大きい(>と記述しても良い) |
<= | 以下(<と記述する) |
>= | 以上(>=と記述しても良い) |
記号 | 説明 |
or | 論理和(左辺が真のときは右辺を評価しない) |
and | 論理積(左辺が偽のときは右辺を評価しない) |
このとき「<」は属性や要素内に記述できない(タグの始まりとみなされる)ので、定義済み実体参照「<」を使用します(LIST4[1])。 文字列と比較する場合には文字列を引用符で囲みます(LIST4[2])。
LIST4:XPathの述部の記述例
● XML文書
<売上表>
<商品コード="XML001">
<品名>XMLマウスパット</品名>
<単価>500</単価>
<数量>2</数量>
</商品>
<商品コード="XML002">
<品名>XMLボールペン</品名>
<単価>150</単価>
<数量>20</数量>
</商品>
</売上表>
● 記述例
<xsl:apply-templates select="売上表/商品[数量<5]" /> ……………… [1]
<xsl:apply-templates select="売上表/商品[@コード='XML001']" /> … [2]
<xsl:apply-templates select="売上表/商品[単価*数量<2000]" /> … [3]
<xsl:apply-templates select="売上表/商品[1]" /> …………………… [4]
<xsl:apply-templates select="売上表/商品[補足]" /> ……………… [5]
また、ノードが数値である場合には算術演算子(表6)によって計算することもできます。なお、除算で一般に使われる「/」はXPathの区切り文字と重なってしまうため、「div」を使用します。 演算結果は関係演算子で条件として記述することもできます(LIST4[3])。
表6:XPathで使用できる算術演算子
記号 | 説明 |
+ | 加算 |
- | 減算 |
* | 乗算 |
div | 除算 |
mod | 剰余 |
[2]数値になるもの
コンテキストノードに対する位置を指します。位置は1から数えます(LIST4[4])。
[3]ノードセットになる場合
ノードセットが空でない場合はtrueとなり、空のときはfalseとなります。つまり、そのノードが存在するかどうかを表わします(LIST4[5])。
[4]文字列になる場合
文字列の長さが1以上の場合にはtrueとなり、文字列の長さが0のときはfalseとなります。
述部はロケーションステップごとに記述できます。例えば、「カタログ[@発売='10月']/商品[@コード='XML001']」と記述すると、発売属性の値が「10月」となっているカタログ要素の子要素である商品要素の中で、コード属性の値が「XML001」となっている商品要素を指定できます。
また、述部は複数記述することもできます。例えば、「商品[数量>10][単価>1500]」と記述すれば、商品要素の子要素である数量要素の値が10より大きい商品要素のうち、単価要素の値が1500より大きい商品要素を指定できます。
XPath関数
XPath式には関数が用意されており、関数を利用してノードに対するさまざまな処理が行なえます。代表的なXPath関数を表7に示します。
表7:代表的なXPath関数
関数 | 説明 |
count(node-set) | ノードセットに含まれるノード数を返す |
position() | コンテキストにおける位置を返す。1から始まる |
last () | コンテキストにおける最後の位置を返す |
string(object) | 引数に指定されたオブジェクトの文字列値を返す |
starts-with(string,string) | 第1 引数の文字列が第2 引数の文字列で始まっていればtrue、そうでなければfalseを返す |
substring-before(string,string) | 第1 引数の文字列のうち、第2 引数の文字列と一致する位置より前の部分の文字列を返す |
substring-after (string,string) | 第1 引数の文字列のうち、第2 引数の文字列と一致する位置より後ろの部分の文字列を返す |
substring (string,num,num) | 第1 引数の文字列のうち、第2 引数に指定された位置から、第3 引数に指定された長さ分までの部分文字列を返す。第2 引数が省略された場合は文字列の末尾までを返す |
normalize-space(string) | 指定された文字列の前後の空白を取り除き、連続する空白文字を1つの空白文字に置き換えた文字列を返す |
not(boolean) | 引数の値がtrueならfalse、falseならtrueを返す |
sum(node-set) | ノードセットの文字列値を数値に変換した合計を返す |
関数の引数にnode-setが指定されているものは、ロケーションパスによってノードセットが選択されるように指定することで、ノードセットの要素数を数えたり、合計を求めたりできます。
引数がstringとなっているものは直接文字列値を指定したり、ロケーションパスにより要素のテキストノードの値を指定したりできます。また、引数がnumとなっているものは、数値を指定したりロケーションパスにより要素のテキストノードの値が数値になっているものを指定したりできます。
例えば、sum(買い物/小計)と指定すれば、買い物要素の子要素にあるすべての小計要素の値の合計を求めることができます。また、データベースからXMLとしてデータを出力した場合、文字数固定のフィールドの値としてデータの後ろに余分な空白がついたまま出力されることがあります。このようなときは、normalize-space(商品/品名)と指定すれば品名要素の前後にある余分な空白を取り除いた値を得ることができます。
データの出力
XSLTスタイルシートでは、xsl:value-of命令や属性値テンプレートを使用してXML文書からデータを抽出し、結果をXML文書に出力できます。
xsl:value-ofによるデータの出力
xsl:value-of命令によりselect属性に指定された値を出力できます。ノードが指定されている場合には、そのノードの文字列値が出力されます(表8)。出力される値は、string()関数の返却値と同じになります。
また、ノードセットが選択された場合は最初のノードに対して出力処理を行ないます。これまでに説明してきたXPathの算術演算子を使って計算した結果やXPath関数の返却値を出力できます。
表8:ノードの文字列値
ノードの種類 | 文字列値 |
ルートノード | すべての子孫テキストノードの値を順番に並べたもの |
要素ノード | すべての子孫テキストノードの値を順番に並べたもの |
属性ノード | 正規化された属性値 |
名前空間ノード | 名前空間URI |
処理命令ノード | ターゲット名と空白の次の文字から?>の手前までの文字列 |
コメントノード | コメント文字列 |
テキストノード | 文字列データ |
属性値テンプレートによるデータの出力
要素の内容としてデータを出力する場合には、xsl:value-of命令によって出力できますが、属性値として出力する場合には属性値テンプレートを使用します。属性値として「{XPath}」を記述することにより、指定されたXPathの値を出力できます(図5)。
今月の確認問題
さて、ここまでテンプレートルールの適用方法やXPathの記述方法、データの出力方法について解説してきました。ここで、今回解説した内容がしっかり理解できているかどうか、確認問題で復習してみましょう。
問題1
次のXML文書をXSLTスタイルシートによって変換したとき、変換結果として適切なものを選択してください。ただし、インデントや改行は見やすさのために変更されているものとします。
[XML文書]
<?xml version="1.0" encoding="Shift_JIS"?>
<カタログ>
<タイトル>XML連載記念グッズ</タイトル>
<商品>
<品名>XMLボールペン</品名>
<単価>200</単価>
</商品>
</カタログ>
[XSLTスタイルシート]
<?xml version="1.0" encoding="Shift_JIS"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<xsl:apply-templates select="カタログ/商品"/>
<xsl:apply-templates select="カタログ/補足"/>
</body>
</html>
</xsl:template>
<xsl:template match="/カタログ/商品">
○品名:<xsl:value-of select="品名" /><br/>
○単価:<xsl:value-of select="単価" />円<br/>
</xsl:template>
<xsl:template match="カタログ/商品">
■品名:<xsl:value-of select="品名" /><br/>
■単価:<xsl:value-of select="単価" />円<br/>
</xsl:template>
<xsl:template match="補足">
補足:<br/>
<xsl:value-of select="." /><br/>
</xsl:template>
</xsl:stylesheet>
- <html>
<body>
○品名:XMLボールペン<br>
○単価:200円<br>
</body>
</html> - <html>
<body>
■品名:XMLボールペン<br>
■単価:200円<br>
</body>
</html> - <html>
<body>
○品名:XMLボールペン<br>
○単価:200円<br>
補足:<br>
</body>
</html> -
<html>
<body>
■品名:XMLボールペン<br>
■単価:200円<br>
補足:<br>
</body>
</html>
解説
「/カタログ/商品」と「カタログ/商品」のパターンは同じ優先度のため、後に記述されたテンプレートルールが適用されます。また、補足要素ノードはXML文書に存在しませんので、補足要素ノードに対するテンプレートルールは適用されません。よって、正解はBとなります。
問題2
次のXML文書をXSLTスタイルシートによって変換したとき、「XMLボールペン」という出力をするために(1)に当てはまる正しいXPathの記述を選択してください。
[XML文書]
<?xml version="1.0" encoding="Shift_JIS"?>
<?xml-stylesheet type="text/xsl" href="zaiko.xsl"?>
<売上表>
<商品コード="XML001">
<品名>XMLボールペン</品名>
<単価>150</単価>
<数量>20</数量>
</商品>
<商品コード="XML002">
<品名>XMLマウスパット</品名>
<単価>500</単価>
<数量>2</数量>
</商品>
</売上表>
[XSLTスタイルシート]
<?xml version="1.0" encoding="Shift_JIS"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<xsl:apply-templates select="
" />
</body>
</html>
</xsl:template>
<xsl:template match="商品">
<xsl:value-of select="品名" /><br/>
</xsl:template>
</xsl:stylesheet>
- 売上表/商品[数量<5]
- 売上表/商品[@コード=XML001]
- 売上表/商品[単価* 数量>1500]
- 売上表/商品[0]
解説
XML文書内では「<」の記号を直接記述できませんので、「<」と記述する必要があります。また、文字列と比較する場合は引用符で囲み、引用符で囲まれていない場合は要素ノードを表わすXPath式とみなされます。
また、XPath式では「*」などの演算子を使って計算でき、「>」の記号は直接記述することが可能です。コンテキストノードに対する位置は1から始まります。よって、正しい記述はCです。
問題3
次のXML文書をXSLTスタイルシートによって変換したとき、(1)の部分の変換結果として下記のような結果を得たい。(1)に当てはまる正しい記述を選択してください。
[XML文書]
<?xml version="1.0" encoding="Shift_JIS"?>
<?xml-stylesheet type="text/xsl" href="test03.xsl"?>
<カタログ>
<タイトル>XML連載記念グッズ</タイトル>
<商品>
<品名>XMLボールペン</品名>
<単価>200</単価>
<イメージ>XMLMasterPen.jpg</イメージ>
</商品>
</カタログ>
[XSLTスタイルシート]
<?xml version="1.0" encoding="Shift_JIS"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<h1><xsl:value-of select="カタログ/タイトル" /></h1>
今回の目玉商品はコチラ<br/>
<table border="1" width="400">
<tr><th>商品イメージ</th> ⇒
<th>品名</th><th>価格</th></tr>
<xsl:apply-templates select="カタログ/商品"/>
</table>
</body>
</html>
</xsl:template>
<xsl:template match="商品">
<tr>
<td>
</td>
<td><xsl:value-of select="品名" /></td>
<td><xsl:value-of select="単価" /></td>
</tr>
</xsl:template>
</xsl:stylesheet>
(ページの都合により⇒で折り返しています。)
[変換結果]
<img src="XMLMasterPen.jpg">
- <img src="<xsl:value-of select='イメージ'/>" />
- <img src="string(イメージ)" />
- <img src="XPath(イメージ)" />
- <img src="{イメージ}" />
解説
属性の中には要素を記述できません。またXSLTスタイルシート内で、XSLTの命令でないところに直接XPath式を記述しても処理されません。XSLT の命令でない属性の中にXML文書のデータを出力するには属性値テンプレートを使用します。よって、正しい記述はDです。
* * *
今回はノードの選択とテンプレートルールの適用の仕組み、XPath の記述方法、xsl:value-of 命令や属性値テンプレートによるデータの出力方法について解説しました。特にXSLTスタイルシートでは、XML文書に記述されたデータ項目をどのように変換するかについて、部分ごとにテンプレートルールに分割することにより、スタイルシートの可読性や保守性を向上させることができます。また、XPathをうまく指定することにより、特定のデータだけを出力したり、次回紹介する制御命令と組み合わせることで重複を取り除いたデータを出力したりといったようなこともできるようになります。 次回は、条件分岐や繰り返しなどの制御命令の記述方法や、XML文書からXML文書へ変換するテクニックについて紹介していきます。
鈴木智也(すずきともや)
株式会社東芝OAコンサルタント教育ソリューション技術部に勤務。インストラクタとして、主にXML やプログラミング言語の講座を担当。今年の梅雨はなぜか週末にばかり雨が……。週末のテニスができず運動不足気味です。 この記事が掲載されるころには真っ黒に日焼けしていることでしょう。そろそろ日焼け止めしないと大変なことに……。
<掲載> P.154-160 DB Magazine 2006 October