XSLTはじめます
一年ぶりに更新します。
ヤル気が出てきて自分でもビックリ。
さて、XSLTについて入門として触れていこうかなーとおもいます。
XSLTってなによ?!っていう方は・・・ぐぐってからお越しください、というのもなんですので、
wikipediaでも御覧ください。
簡単にいうと、CSSと並ぶhtml(xml)用のスタイルシートです。
見に来てくださった皆様はきっともう知ってらっしゃいますよね?(という体で・・・)
いきなり2.0勧められてもわかんねーよ!っていう方がおられましたらすいませんでした。
私はXSLTは実務で使用しています。
自分なりの答えなので、間違いがありましてもご容赦ください。
(指摘していただけると幸いです)
ちなみにこの入門も2.0準拠で話を進めたいとおもいます。
だってみつからなかったんだもん
ネット、本ともにXSLTに関する資料は少なくはないのですが、実務での使い方や理想的な組み方について触れている資料は、少なくとも自分が探した範囲ではありませんでした。
多分、帳簿計算、データ抽出やデータトリミングに使われることが多く、変換という観点でのデータ全体の再利用方法のアプローチは、DITAなどのドキュメントデータレベルでしか使用されることが少ないのが原因ではないかなーと思っています。
しかも、DITAやDocBookなどの情報は日本語で解説しているページはあまりありません。
まーすごく日本人的だなーとか思っちゃいます。
入門編 その1
さて、入門するにあたって重要なキーワードが3つあります。
- データモデル
- コンテキストアイテム(旧名称:カレントノード)
- ロケーションパス
はい、出ました。
この3つがわかればXSLTが理解できたも同然です。
けっこうマジな話本当です。
では詳細に入っていこうと思います。
1.データモデル
他のプログラム言語にもあるように、XSLTにもデータ型が決まっています。
1.0と1.1は変わらなかったはずですが、2.0になった時に大きく変更されました。
それがこれだ!
頭痛い系ですね。
W3Cにあるものそのまま持ってきただけです。
全体が理解できていると素晴らしいですが、本当に必要なのはこの部分だけです。
XSLTにおいて、このnode群が全てと言っても過言ではありません。
これを1つずつ見て行きたいと思います。
ちなみに緑色のところは関係ありません。
node:ノード
下記の種類を内包する抽象的なデータ型です。
nodeというデータ型がデータ上に存在するわけではありません。
attribute:属性ノード
属性ですね。属性値とは別物ですので注意してください。
hogehoge=""と表記されます。
comment:コメントノード
コメントですね。
<!-- -->という表記になります。
document:ドキュメントノード・ルートノード
ルートノードと呼ばれることもあります。
多くは対象の入力処理ファイル(xml)のことを指します。
element:要素ノード
要素です。
<div></div>または<div />という表記になります。
processing-instraction:処理命令ノード
これがちょっとわかりにくいですが、多くは先頭に書かれている宣言に使われています。
<?xml version="1.0" encoding="UTF-8"?>
ちなみに、phpの宣言も同じように扱えます。
<?php hogehoge ?>
text:テキストノード
実際の文章データです。
これは、>hogehoge<のようにタグで囲われている部分を指しています。
xml上で再現するとこんな感じでしょうか?
<?xml version="1.0" encoding="UTF-8"?>
<!-- コメント -->
<書籍 出版日="2013-02-24">あまぞん</書籍>
<?processing-instraction ?>
<!-- comment -->
<element attribute="ここはtextではありません">text</element>
データモデルを理解しようと進めていくと、あることに気が付きます。
そう、変数がありません。
XSLTではこのデータモデルに載っていないモデルを扱うことはできません。
通常のDOMなどを使用すると、このへんの扱いもコントロールすることが可能ですが、XSLTでは不可能です。
詳細は省きますが、処理を行う際に変換元のxmlも変換するためのXSLTもプロセッサによってパースされてしまい、そのタイミングで既に変数が消滅しているからということになります。
それも合わせて、XSLTでデータを扱う際にはデータモデルに扱いたいデータ型があるかどうかが大前提になります。
2.コンテキストアイテム
XSLTはデータ駆動であり、処理対象であるxmlにそって変換が行われるわけですが、処理されている現在のアイテム(ノード)位置をコンテキストアイテムと言います。
間違えちゃうから気をつけて!
そもそもコンテキストアイテムという言葉は2.0から使用されるようになりました。
じつは、それまではカレントノードと呼ばれていました。
なぜ名称が変更されたかというと、データモデルが増加し、モデルの頂点がItemとなったためです。
そのため使用する関数などにcurrentという名残があります。
カレントアイテムにならなかったのは、データ型がノードだけではなくなり、必ずしも処理対象のxml上に存在するわけではなくなったためです。
最初はピンとこないとおもいますので、データモデルが大きく変更されたためとおぼえておいてください。
XSLTの2.0とそれ以前の資料が混ざってしまい、コンテキストだのカレントだの書かれていますが言ってしまえば”ほぼイコール”ということになります。
以下では全てコンテキストアイテムに統一します。
実際の変換を行なってみると、厳密な型管理を行うにはそれなりに仕込みをしなければなりませんので、実際にはノード群を扱うことが殆どになると思います。
さて、じゃあ結局”
コンテキストアイテム”とはなんなんだという話になるんですが、処理上での現在位置ということになります。
表現の一例を出してみます。
正しい表現
- コンテキストアイテムはノード
- コンテキストアイテムは要素、コンテキストアイテムは要素ノード、コンテキストアイテムはdiv要素
- コンテキストアイテムはコメント、コンテキストアイテムはコメントノード
誤った表現
- コンテキストアイテムはdiv→データモデルがどれなのかわかりません。
- コンテキストアイテムはxsl:template要素→変換対象のxml上のアイテムしかコンテキストアイテムになりえません。
XSLTではコンテキストアイテム(現在位置)から何をどうしたいのか、という記述の塊になります。
なので、すべての基準がコンテキストアイテムになる、ということになります。
コンテキストアイテムを変更できるXSLT要素は限られており、コンテキストアイテムの変更は柔軟にはできません。
変更方法については、今回は飛ばします。
3.ロケーションパス
ロケーションパスは、コンテキストアイテムからの相対的な位置を表します。
じゃあ、なんの位置を表すんだよ?ということになると思いますが、それは場所や用途によって変化します。