ラベル Saxon の投稿を表示しています。 すべての投稿を表示
ラベル Saxon の投稿を表示しています。 すべての投稿を表示

2013年2月24日日曜日

【XSLT】入門編 その1

XSLTはじめます

一年ぶりに更新します。
ヤル気が出てきて自分でもビックリ。

さて、XSLTについて入門として触れていこうかなーとおもいます。

XSLTってなによ?!っていう方は・・・ぐぐってからお越しください、というのもなんですので、wikipediaでも御覧ください。

簡単にいうと、CSSと並ぶhtml(xml)用のスタイルシートです。
見に来てくださった皆様はきっともう知ってらっしゃいますよね?(という体で・・・)

いきなり2.0勧められてもわかんねーよ!っていう方がおられましたらすいませんでした。

私はXSLTは実務で使用しています。
自分なりの答えなので、間違いがありましてもご容赦ください。
(指摘していただけると幸いです)

ちなみにこの入門も2.0準拠で話を進めたいとおもいます。

だってみつからなかったんだもん

ネット、本ともにXSLTに関する資料は少なくはないのですが、実務での使い方や理想的な組み方について触れている資料は、少なくとも自分が探した範囲ではありませんでした。

多分、帳簿計算、データ抽出やデータトリミングに使われることが多く、変換という観点でのデータ全体の再利用方法のアプローチは、DITAなどのドキュメントデータレベルでしか使用されることが少ないのが原因ではないかなーと思っています。

しかも、DITAやDocBookなどの情報は日本語で解説しているページはあまりありません。
まーすごく日本人的だなーとか思っちゃいます。

入門編 その1

さて、入門するにあたって重要なキーワードが3つあります。
  1. データモデル
  2. コンテキストアイテム(旧名称:カレントノード)
  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">あまぞん</書籍>

document

<?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.ロケーションパス

ロケーションパスは、コンテキストアイテムからの相対的な位置を表します。
じゃあ、なんの位置を表すんだよ?ということになると思いますが、それは場所や用途によって変化します。































2012年2月18日土曜日

【XSLT】2.0使っちゃいなよ

すごい久しぶりの更新。

ゆっくりやっていきたいと思います。

今回はXSLTについて。

あまり周りで使われてるのを見ないのでマイノリティ扱いです。
だって、マイノリティですよね??

XMLの変換では最強(一部処理できない部分を除き)かと思いますが、
得意な言語があればそれで処理してしまうもののようです。
だからこそマイノリティなのですが。

今後、ePubなどの電子書籍に向けた変換サービスでちょっと流行りそうではありますが。
まぁ、それでもマイノリティー┐(´∀`)┌

仕事の都合でいきなり2.0から習得したもので、1.0とか1.1での不便をあまり感じていない今日この頃ですが・・・

1.0とか1.1での問題につまいづいてたら、2.0へ行ったほうが早いと思います。
それでもダメなものは、XSLTの領分を超えてる問題ですね。

いろんな意味でSaxonさまさまです。

特に正規表現が使えるようになって、テキストノードへの複雑なアクセスが簡単になったのが一番大きいのかな?

2.0機能で自分がよく使うのは↓な感じ
  1. variable as="item()*"
  2. analyze-string
  3. result-document
  4. for-each-group
  5. function

使ったら面白そうだけど、使ってないのはfor-eachでの整数ループとか。

特に、1の変数へのノード格納はとても大きいかと思われます。はい。
1.0で出来なかった連想配列を、ノードを利用することで簡単に作れます。

でも、ちょっと問題があって、
やっててわかったこと(自分の周りも含め)は、XSLTのデータモデルへの理解不足と、コンテキストアイテム(1.0ではカレントノード)への理解不足ですね。

実際、XSLTを書く際の肝は↓をどれだけ理解できてるか、かと思います。
  • コンテキストアイテム
  • データモデル
  • 組み込みテンプレート
この3つを理解できてれば、できない事なんて無いんじゃないですかね??
組み込みテンプレートは慣れとしか言えないですが。
他の言語でよく言われる”おまじない”が隠匿してあるだけっていう。

わかっちゃえば、modeとかpriorityとかちょっと凝ってきても無問題だし。

初心者向けに情報をまとめたら見る人いるのかな?
いるならコメントください。書く気出ます。

で、2.0ですが、プロセッサがSaxonしかないのでSaxon無双な状態なんですが、
プロセッサが変更になるとプロセッサごとの微妙な違いで、出力されるデータに差異が生じることがあるので要注意です。

W3Cで策定されたXSLT2.0では処理内容については明確に定義されていないのが起因しています。

なのでSaxonではないプロセッサを使用していて、2.0へ移行するのは要注意ですね。

Saxonは3.0 Daftの一部が実装されているので、それを試してみても面白いかもです。
(Saxonの独自機能も面白そうですが、この先でどうなるかわからんのでアレですが。)

さて、コーディングにもどりますノシ