XMLマスターへの道
〜「XMLマスター:ベーシック」試験対策〜
第11回 XSLTで必須の制御命令を覚える
内藤一彦NRIラーニングネットワーク株式会社
2003/11/27
前回「第10回 XSLTの基本構造を理解する」では、XML文書を変換するXSLTの基本構造について紹介しました。今回は、前回の内容を踏まえて、より多くのパターンに応用できるXSLT命令について紹介します。前回で予習問題として下記の問題を出題しておきました。この問題を解くための解説をした後、解答を示します。
今回の問題 | ||||||||||
(Q1) 次のような学生一覧のXML文書があるときに、学年・クラス・出席番号の順でソートを行い処理したい。このときの、ソートの記述方法として正しいのはどれでしょう。
|
||||||||||
(Q2) 組み込みテンプレートとして正しいものをすべて選択してください。
|
今回は、この問題に解答するうえで必要となる下記の内容について解説します。
- さまざまな制御命令
- 繰り返し(xsl:for-each)
- 条件付き処理(xsl:if)
- 条件分岐(xsl:choose)
- ソート(xsl:sort)
- 新しいノードの作成
- 要素ノード(xsl:element)/属性ノードの作成(xsl:attribute)
- 出力指定(xsl:output)
- 組み込みテンプレート
今回は、命令の書き方が中心となります。非常によく使われるものをピックアップしていますので、実際にサンプルを動かしたり、自分で作って検証してください。
繰り返し(xsl:for-each)
xsl:for-eachは指定されたノードを取り出しながら処理を繰り返します。そして取り出すノードがなくなると、繰り返しから抜けます。
●xsl:for-eachの構文 |
|
<?xml version="1.0" encoding="Shift_JIS" ?> |
リスト1 変換元のXML文書(for-each.xml) |
<?xml version="1.0" encoding="Shift_JIS" ?> |
リスト2 XSLTスタイルシート文書(for-each.xsl) |
上記のリスト1、for-each.xmlの2行目に
<?xml-stylesheet type="text/xsl" href="for-each.xsl" ?> |
を挿入し、for-each.xmlをIE 6.0で開くと次のようになります。
図1 IE 6.0でfor-each.xmlを表示 |
参考
このサンプルではxsl:for-eachを使用してそれぞれのEMPLOYEEを処理していますが、xsl:apply-templatesを使用しても同様の結果を得ることができます。
<?xml version="1.0" encoding="Shift_JIS" ?> |
リスト3 xsl:apply-templatesを使用するスクリプト |
条件付き処理(xsl:if)
xsl:ifは条件を評価して、条件が成り立った場合にのみ処理を行います。一般的なプログラム言語では「if 〜then〜else〜」というように、条件が成り立った場合と成り立たなかった場合の処理を記述できますが、xsl:ifでは成り立った場合の処理のみ記述します。
●xsl:ifの構文 |
|
test属性で指定する条件には、trueかfalseを返す式を記述します。また、条件式の中で「<」「>」「'」「"」「&」など特殊記号を使用する場合、そのまま使うと誤って解釈されたりエラーが発生する可能性があるので、定義済み実体を利用します(「第4回 すべてのXML文書は整形式である 表3 定義済み実体」参照)。
例えば、
「salary<300000」という条件を記述したいのであれば
test="salary<300000" |
「dept="sales"」(dept要素がsalesという文字列)であれば、
test="dept='sales'" |
または
test="dept='sales'" |
とします。
条件分岐(xsl:choose)
xsl:chooseはxsl:whenやxsl:otherwiseと組み合わせて使用します。
●xsl:chooseの構文 |
|
- xsl:when:1つ以上記述する。記述されている順にtest属性が評価され、条件が成り立った場所の処理を行う
- xsl:otherwise:最後に1つだけ記述するか、記述しなくても構わない。いずれのxsl:whenの条件も成り立たなかった場合に処理が行われる
ここで、xsl:ifとxsl:chooseを使用している例を紹介します。
<?xml version="1.0" encoding="Shift_JIS" ?> |
リスト4 変換元のXML文書(employee.xml) |
<?xml version="1.0" encoding="Shift_JIS" ?> |
リスト5 XSLTスタイルシート文書(if-choose.xsl) |
上記リスト4、employee.xmlの2行目に
<?xml-stylesheet type="text/xsl" href="if-choose.xsl" ?> |
を挿入し、employee.xmlをIE 6.0で開くと次のようになります。
図2 IE 6.0でemployee.xmlを表示 |
xsl:if の部分では、Salaryが400000以上(Salary>=400000)であれば、社員の名前を表示するようにしています。
また、xsl:chooseでは、
- Salaryが500000以上ならば[Over 500000]
- Salaryが400000以上500000未満ならば[Between 400000 and 500000]
- それ以外(Salaryが400000未満)ならば[Under 400000]
と表示されるようにしています。
xsl:sortを使うとノードを取り出すときにソートを行います。記述方法は難しくありませんが、使い方に注意が必要です。
●xsl:sortの構文 |
|
- select属性:ソートキーとなるノードを指定
- data-type属性:text (文字としてソート)、number(数値としてソート)。省略時はtextが採用される
- order属性:ascending (昇順)、descending(降順)。省略時はascendingが採用される
さて、これをどこに記述するかです。記述できる場所は、xsl:apply-templates要素かxsl:for-each要素の中だけです。ともに、xsl:sortを使用していない場合にはノードの処理順序はそのままデータの記述どおりの順序となります。
ですから、前述のサンプル(for-each.xslやif-choose.xsl)ではEMPLOYEEの処理は記述されている順番どおりとなっています。これにソートを加えたいのであれば、次のようにxsl:sortを加えます。これにより、ソートを行った結果の順序でノードの処理を行ってくれます。
<xsl:template match="/" > |
リスト6 xsl:sortを加えたスクリプト |
また、xsl:sortを並べて記述すると複次ソートの指定となりますので、入れ子にせずに記述します。
前回の予習問題の解答となりますが、次のように学生名簿で、学年・組・出席番号の順で複次ソートを行うことができます。
<?xml version="1.0" encoding="Shift_JIS" ?> |
リスト7 変換元のXML文書(sort.xml) |
<?xml version="1.0" encoding="Shift_JIS" ?> |
リスト8 XSLTスタイルシート文書(sort.xsl) |
上記のリスト7のsort.xmlの2行目に
<?xml-stylesheet type="text/xsl" href="sort.xsl" ?> |
を挿入し、sort.xmlをIE 6.0で開くと次のようになります。
図3 IE 6.0でsort.xmlを表示 |
■ノードの作成
要素ノード(xsl:element)/属性ノードの作成(xsl:attribute)
ここまではHTMLやほかのXML形式に変換する場合、スタイルシートの中にタグを直接記述してきましたが、専用のXSLT命令を使って生成することもできます。
●xsl:elementの構文 |
|
●xsl:attributeの構文 |
|
<?xml version="1.0" encoding="Shift_JIS" ?> |
リスト9 変換元のXML文書(employee2.xml) |
このXMLを次のような別のXML構造に変換します。
図4 XML構造を変更する |
<?xml version="1.0" encoding="Shift_JIS" ?> |
リスト10 XSLTスタイルシート文書(elemTrans.xsl) |
上記リスト9のemployee2.xmlの2行目に
<?xml-stylesheet type="text/xsl" href="elemTrans.xsl" ?> |
を挿入し、employee2.xmlをIE 6.0で開きます。その後、ウィンドウ内で右クリックしメニューから「View XSL Output」を実行します(「Viewing XSLT Output」ツールは、第5回と第10回の記事中で紹介しています)。
図5 View XSL Output での表示内容 |
作成する要素に「要素の値」と「属性」を持たせる場合、注意する点があります。それは、属性を作成する要素には、すでに子ノードがあってはいけないということです。従って、サンプルで記述している「属性の作成」と「要素の値の作成」の順番が逆になるとエラーが発生します。必ず、属性が作成されてから要素の値や子要素を作成するようにしなければなりません。
<xsl:element name="EMP"> |
リスト11 正しい記述 |
<xsl:element name="EMP"> |
リスト12 エラーが発生 |
■出力指定(xsl:output)
xsl:outputを使用すると変換によって得られるドキュメントの形式やインデントの有無などを指定できます。また、xsl:outputはトップレベル要素であるため、必ずルート要素であるxsl:stylesheetの直系の子として記述します。
●xsl:outputの構文 |
|
method属性:xml、html、textを指定 |
method="html"の動作
HTMLに変換する場合、使用したいHTMLタグをXSLTスタイルシートの中で直接記述することができます。ただし、HRやBRなどを使用する場合、注意が必要です。これらのタグはHTMLでは、終了タグは必要としません。
<xsl:template match="/" > |
リスト13 エラーが発生 |
しかし、リスト13のように、HTMLのルールに従ってBRタグを記述するとエラーが発生します。なぜなら、HTMLタグという以前にこのXSLTファイルはXML形式でなければならないので、開始タグに対応する終了タグが必要となるからです。エラーにならないためには、次のように記述する必要があります。
<xsl:template match="/" > |
リスト14 正しいHTMLタグの記述 |
このような場合に、method="html"が指定されていると、変換時にHTML形式を考慮して終了タグを自動的に削除して出力します。
method属性が省略されている場合、出力するドキュメントのルート要素が、<HTML>(大文字・小文字を問わない)で始まっている場合には、自動的にmethod="html"を採用します。それ以外の場合には、method="xml"を採用します。
method="text"の動作
この場合、すべてのテキストノードのみが出力されます。従って、出力されるのは要素の値部分のみです。
そのほかの属性としては、次のようなものがあります。
- encoding属性:出力ドキュメントの文字エンコーディング方式
- omit-xml-declaration属性:「yes」または「no」。XML宣言、テキスト宣言を出力するかしないか
- indent属性:「yes」または「no」。インデントするかしないか
XSLTではあらかじめ組み込まれているテンプレートとして次の3種類があります。これらは、テンプレートの呼び出し方法が間違っていたなどの理由で、ユーザーが記述していないテンプレートの呼び出しを行った場合に、呼び出されます。
- ルートノードまたはすべての要素ノード用のテンプレート(すべての子ノードに対してテンプレート呼び出しを実行する)
<xsl:template match="*|/" >
<xsl:apply-templates />
</xsl:template>
- すべてのテキストノードまたはすべての属性ノード用のテンプレート(自分の値を取得する)
<xsl:template match="text()|@*" >
<xsl:value-of select="." />
</xsl:template>
- すべてのXSLT処理命令ノードまたはすべてのコメントノード用のテンプレート(何もしない)
<xsl:template match="processing-instruction()|comment()" />
極端な例ですが、次のようなXSLTスタイルシートでもエラーが発生することなく変換が行われます(すべての要素・属性の値が出力されます)。
<?xml version="1.0" encoding="Shift_JIS" ?> |
リスト15 すべての要素・属性の値が出力されるスクリプト |
■今回の問題の解答
それでは、予習問題の解答を解説いたします。
(Q1) 次のような学生一覧のXML文書があるときに、学年・クラス・出席番号の順でソートを行い処理したい。このときの、ソートの記述方法として正しいのはどれでしょう。
答えは、(d)です。
複次ソートを行う場合、
|
というように、xsl:sortを記述していきます。
「さまざまな制御命令」の「ソート(xsl:sort)」で、この問題をサンプルに取り上げていますので、もう一度確認しておきましょう。
(Q2) 組み込みテンプレートとして正しいものをすべて選択してください。答えは、(a)、(b)、(c)です。
組み込みテンプレートとしては、3種類あります。それらが、この問題での解答となる3つです。記述されていないテンプレートが誤って呼び出された場合など、これらのテンプレートが呼び出され処理されます。「組み込みテンプレート」で解説していますので、もう一度確認しておきましょう。node() (すべてのノード)に対するテンプレートは用意されていません。
■次回の予習問題
次回のために予習問題を掲載します。次回はXPathです。XSLTと非常に密接な関係にあり、XSLTにはなくてはならない機能です。
予習問題 | ||||
|
||||
(Q1) 共通のXMLからSalaryが400000以上の社員情報を取得したい。共通のXSLTのテンプレートの(1)に入れるべき記述として正しいものを選択してください。
|
||||
(Q2) 共通のXMLのEMPLOYEEのうち、先頭の2件(データの記述順)の社員情報を取得したい。共通のXSLTのテンプレートの(1)に入れるべき記述として正しいものを選択してください。
|
○今回の試験対策のポイント
- さまざまな制御命令
- 繰り返し(xsl:for-each)
- 条件付処理(xsl:if)
- 条件分岐(xsl:choose)
- ソート(xsl:sort)
- 新しいノードの作成
- 要素ノード(xsl:element)/属性ノードの作成(xsl:attribute)
- 出力指定(xsl:output)
- 組み込みテンプレート
○今回の学習内容で出題範囲となる仕様
○今回の学習内容で実機確認を行うときに役立つフリーツール
- Internet Explorer 6.0 SP1 以上
- Microsoft
XML Parser (MSXML) 3.0 Service Pack 4 (SP4) - 日本語
※ 別途、Xmlinst.exe Replace Mode Toolが必要になる場合あり(詳細はMicrosoft XML Parser Version 3.0 Releaseの新機能をご参照ください) - Internet Explorer Tools for Validating XML and Viewing XSLT Output
○今回の学習内容で参考になる@ITの記事
- XSLTスタイルシート書き方講座
- サンプルで覚えるXSLTプログラミング
- XMLテクニック集
- いまさら聞けない、技術者のためのXML再入門 第7回 XML文書の構造を変えるXSLT
- VBScriptでXMLプログラミング(3) XSL/XSLTを利用したデータの変換と整列
○今回の学習内容で参考になるXML用語集 (@IT XML用語事典より)
(12)XPathによるノードの指定法を理解する |
連載:XMLマスターへの道 |
- QAフレームワーク:仕様ガイドラインが勧告に昇格 (2005/10/21)
データベースの急速なXML対応に後押しされてか、9月に入って「XQuery」や「XPath」に関係したドラフトが一気に11本も更新された - XML勧告を記述するXMLspecとは何か (2005/10/12)
「XML 1.0勧告」はXMLspec DTDで記述され、XSLTによって生成されている。これはXMLが本当に役立っている具体的な証である - 文字符号化方式にまつわるジレンマ (2005/9/13)
文字符号化方式(UTF-8、シフトJISなど)を自動検出するには、ニワトリと卵の関係にあるジレンマを解消する仕組みが必要となる - XMLキー管理仕様(XKMS 2.0)が勧告に昇格 (2005/8/16)
セキュリティ関連のXML仕様に進展あり。また、日本発の新しいXMLソフトウェアアーキテクチャ「xfy technology」の詳細も紹介する
|
|