このお盆休みの期間を使って、久しぶりに XSL を再勉強しました。10年くらい前の以前に使っていたころと比べて事情も変わっていたようで、リスキリングという意味でもいい機会だったと思っています。改めて「そもそも XSL とは?」から「なんで XSL をやり直そうと思ったのか」という背景も含め、まとめておきます。実はこの背景部分が少々複雑で、眺めの導入説明になっている点をご了承ください。
【HTML と CSS の関係】
XSL のブログエントリでなんで HTML と CSS ? と感じる人もいると思いますが、実はこれが上述の背景部分に絡んできます。 ウェブのデザインをしたことがある人はわかっていることだと思いますが、ウェブページって、
・表示するデータを HTML で
・その見栄えは CSS で
定義することになっています。極端な言い方をすると HTML 内には見栄えに関連する要素を入れずに(HTML5 以降では見栄えに関する要素は排除される方向です)、見た目はすべて CSS で、というやり方。これはこれでメリット・デメリットある気がしますが、役割分担としてはシンプルで悪くないと感じています。
ただ、自分はこの考え方に少し違和感があります。「見栄えを CSS で」という点はいいのですが、「表示するデータを HTML で」という部分は現実と少し違っているように感じてしまうのでした。
例えばこんな HTML があったとします:
一見なんの変哲もない、<h1> の見出しと成績表が定義された HTML です。これらの見出しや表部分、細かくは全体のフォントや背景色なども含めて具体的にどのような見栄えになるのかは別途 CSS で定義する、というものです。 ここで私が「表示するデータは HTML で定義」していることについて違和感を感じるのは「<title> と <h1> の両方で "成績表" が定義されていること」です。
これは HTML 的にはブラウザウィンドウのタイトル部分(<title>)と、ブラウザ内に表示されるウェブページとしての見出し部分(<h1>)なので別々に定義する必要があるものです(別々に定義しようと思えばできる、という点ではその通り)。一方で「データとして」考えるとどちらも「見出し」のデータであって、「別々に定義するつもりがないのであれば、データとしては1つ」が正しいものです。後者の考え方でウェブページを作ろうとすると、「データを定義するはずの HTML 内で <title> と <h1> の2か所で同じ内容を(2重に)定義している」とも感じます。これはもちろん HTML の仕様ともかかわる問題ではあるのですが、その HTML の仕様のせいでデータを2重管理する必要が生じてしまっているのでした。
2重管理しないといけないものが「表示するデータを定義するもの」・・・これが私の感じた違和感でした。本来「表示データ」は2重、3重に定義せず正規化されているべきものであって、その内容を表示ページの内容に従って HTML に配置しなおして(ここで2重化されるのは理解できる)、最後に CSS で HTML の見栄えを定義する、という考え方がしっくりくるのでした。 要するに「HTML が表示データの定義」と呼ぶことに抵抗を感じていて、「表示データをウェブページの配置に沿って変換した結果が HTML」と考えるとすっきり理解しやすいのでした:
(※この後 msxsl.exe というツールを使う関係でわざと XML に encoding="Shift_JIS" 指定を加えています。msxsl.exe を使わない場合は encoding 指定なしで(UTF-8 で)構いません)
【XSL とは】
XSL(eXtensible Stylesheet Language) は上述の「表示データをウェブページの配置に沿って変換した結果が HTML」の「変換ルール」に関わるものです。そして実際の変換処理そのものは XSLT(XSL Transform) と呼びます。
具体的に XML と XSL を用意して、XSLT を行ってみます。まず以下のような2つのテキストファイル data.xml と data.xsl を用意します(いずれもシフト JIS エンコードで保存してください):
(data.xml)
(data.xsl)
【参照】
XSLTの使い方・入門チュートリアル
data.xml が表示データの定義ファイルで、data.xsl が data.xml を HTML に変換する際の変換ルールを定義しています。<xsl:template match="/"> と </xsl:template> の間で HTML が定義されていて、<xsl:value-of> と <xsl:for-each> を使って表示データ(data.xml)のテキスト値や属性値を HTML に変換しています。
XML と XSL を使って HTML に変換(= XSL Transform)する方法はいくつかありますが、比較的簡単なマイクロソフト製コマンドラインツール msxsl.exe を使った例を紹介します、、が、このツールは便利ではあるのですが、かなり古いものらしく、マイクロソフトのサイトには存在しておらず、インターネットアーカイブ上でしか見つけることができませんでした。というわけでこちらからダウンロードしてください:
http://web.archive.org/web/20140812045521/http://www.microsoft.com/en-us/download/details.aspx?id=21714
ダウンロードできたら Windows 上でコマンドプロンプトを開き、data.xml , data.xsl の存在するフォルダに移動します。そして msxsl.exe にパスを通すか、data.xml, data.xsl と同じフォルダに msxsl.exe をコピーしてください。
準備ができたら以下を実行します:
msxsl.exe は2つのパラメータを指定して XSLT 処理を実行します。最初のパラメータが XML ファイルのパス、2つ目のパラメータが XSL ファイルのパスです。正しく実行できた場合は XSLT の実行結果が画面上に表示されます:

※このコマンドプロンプト画面ではシフト JIS でないと文字化けを起こしてしまいます。その理由もあって data.xml と data.xsl をシフト JIS で作ったという背景があるのでした。
個人的には XSLT 処理をプログラミング内で行うこともあるのですが、そこでうまくいかないケースに遭遇した場合、この msxsl.exe を使うとエラー発生時の内容や箇所をエラーメッセージとして表示してくれるので、主にデバッグ目的で今でもよく使っています。
この XSL(T) を使うことで、
・表示するデータは XML で、
・XML を XSL を使って変換した HTML を使って、
・HTML の見栄えは CSS で、
それぞれ役割分担して定義する、ということが可能になります。例えばデータベースから取り出した直後のデータは XML に近い形をしていることが多いので、そこから HTML を生成する際に XSL を使い、細かな見栄えは別途 CSS で定義する、という役割分担が、自分の理解の上でも腹落ちしやすいと考えています。
【ノーツのデータ構造に似ている】
ここまでに紹介してきた XML と XSL の関係というのが、HCL ノーツ/ドミノでいうところの「文書(document)」と「フォーム(form)」の関係に似ていると思っています。ノーツではデータそのものは文書として格納されていて、その見栄えは適用されるフォームによって定義されています。同じ文書でも適用さえるフォームによって見栄えが変わる点も含めて似ているのですが、加えてノーツのデータは DXL(Domino XML Language) という特殊な XML フォーマットでインポート/エクスポートできる機能があるので、XML/XSL との相性も悪くなかったりします。
まあ現実のノーツデータはそこまで単純ではありません。ノーツにはサブフォームや共有フィールドといった設計の再利用の仕組みがあったり、HTML とは異なる独特なリッチテキスト編集/保存機能があったり、細かな所では XSL のテンプレート名称に使ってよい文字とノーツのフォーム/サブフォーム名に使ってよい文字に違いがあったりして、単純に XML/XSL 対応ができるわけではなかったりします。
とはいえ、それでもノーツのデータをノーツ外で取り扱う(これ自体がすごくハードルの高いことだったりします)ことを目指そうとすると、 DXL にエクスポートした上で XML/XSL の仕組みをベースにすることでノーツ外でも取り扱いできるようにするための近道のようには感じています。どこまで実現できるかわからないのですが、個人的にそんなツールの開発を始めていて、いずれどこかで紹介できればと思っています。
【HTML と CSS の関係】
XSL のブログエントリでなんで HTML と CSS ? と感じる人もいると思いますが、実はこれが上述の背景部分に絡んできます。 ウェブのデザインをしたことがある人はわかっていることだと思いますが、ウェブページって、
・表示するデータを HTML で
・その見栄えは CSS で
定義することになっています。極端な言い方をすると HTML 内には見栄えに関連する要素を入れずに(HTML5 以降では見栄えに関する要素は排除される方向です)、見た目はすべて CSS で、というやり方。これはこれでメリット・デメリットある気がしますが、役割分担としてはシンプルで悪くないと感じています。
ただ、自分はこの考え方に少し違和感があります。「見栄えを CSS で」という点はいいのですが、「表示するデータを HTML で」という部分は現実と少し違っているように感じてしまうのでした。
例えばこんな HTML があったとします:
<html> <head> <title>成績表</title> </head> <body> <h1>成績表</h1> <table id="mytable"> <thead> <tr><th>名前</th><th>国語</th><th>数学</th></tr> </thead> <tbody> <tr><td>佐藤</td><td>50</td><td>90</td></tr> <tr><td>鈴木</td><td>70</td><td>60</td></tr> <tr><td>田中</td><td>80</td><td>40</td></tr> </tbody> </table> </body> </html>
一見なんの変哲もない、<h1> の見出しと成績表が定義された HTML です。これらの見出しや表部分、細かくは全体のフォントや背景色なども含めて具体的にどのような見栄えになるのかは別途 CSS で定義する、というものです。 ここで私が「表示するデータは HTML で定義」していることについて違和感を感じるのは「<title> と <h1> の両方で "成績表" が定義されていること」です。
これは HTML 的にはブラウザウィンドウのタイトル部分(<title>)と、ブラウザ内に表示されるウェブページとしての見出し部分(<h1>)なので別々に定義する必要があるものです(別々に定義しようと思えばできる、という点ではその通り)。一方で「データとして」考えるとどちらも「見出し」のデータであって、「別々に定義するつもりがないのであれば、データとしては1つ」が正しいものです。後者の考え方でウェブページを作ろうとすると、「データを定義するはずの HTML 内で <title> と <h1> の2か所で同じ内容を(2重に)定義している」とも感じます。これはもちろん HTML の仕様ともかかわる問題ではあるのですが、その HTML の仕様のせいでデータを2重管理する必要が生じてしまっているのでした。
2重管理しないといけないものが「表示するデータを定義するもの」・・・これが私の感じた違和感でした。本来「表示データ」は2重、3重に定義せず正規化されているべきものであって、その内容を表示ページの内容に従って HTML に配置しなおして(ここで2重化されるのは理解できる)、最後に CSS で HTML の見栄えを定義する、という考え方がしっくりくるのでした。 要するに「HTML が表示データの定義」と呼ぶことに抵抗を感じていて、「表示データをウェブページの配置に沿って変換した結果が HTML」と考えるとすっきり理解しやすいのでした:
(表示データの定義(の XML 例)) <?xml version="1.0" encoding="Shift_JIS"?> <成績表> <見出し>成績表</見出し> <結果 名前="佐藤" 国語="50" 数学="90"/> <結果 名前="鈴木" 国語="70" 数学="60"/> <結果 名前="田中" 国語="80" 数学="40"/> </成績表> ↓(変換)
(表示ウェブページの HTML) <html> <head> <title>成績表</title> </head> <body> <h1>成績表</h1> <table id="mytable"> <thead> <tr><th>名前</th><th>国語</th><th>数学</th></tr> </thead> <tbody> <tr><td>佐藤</td><td>50</td><td>90</td></tr> <tr><td>鈴木</td><td>70</td><td>60</td></tr> <tr><td>田中</td><td>80</td><td>40</td></tr> </tbody> </table> </body> </html>
(※この後 msxsl.exe というツールを使う関係でわざと XML に encoding="Shift_JIS" 指定を加えています。msxsl.exe を使わない場合は encoding 指定なしで(UTF-8 で)構いません)
【XSL とは】
XSL(eXtensible Stylesheet Language) は上述の「表示データをウェブページの配置に沿って変換した結果が HTML」の「変換ルール」に関わるものです。そして実際の変換処理そのものは XSLT(XSL Transform) と呼びます。
具体的に XML と XSL を用意して、XSLT を行ってみます。まず以下のような2つのテキストファイル data.xml と data.xsl を用意します(いずれもシフト JIS エンコードで保存してください):
(data.xml)
<?xml version="1.0" encoding="Shift_JIS"?> <成績表> <見出し>成績表</見出し> <結果 名前="佐藤" 国語="50" 数学="90"/> <結果 名前="鈴木" 国語="70" 数学="60"/> <結果 名前="田中" 国語="80" 数学="40"/> </成績表>
(data.xsl)
<?xml version="1.0" encoding="Shift_JIS"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="html" encoding="Shift_JIS"/> <xsl:template match="/"> <html> <head> <title><xsl:value-of select="成績表/見出し" /></title> </head> <body> <h1><xsl:value-of select="成績表/見出し" /></h1> <table id="mytable"> <thead> <tr><th>名前</th><th>国語</th><th>数学</th></tr> </thead> <tbody> <xsl:for-each select="成績表/結果"> <tr> <td><xsl:value-of select="@名前" /></td> <td><xsl:value-of select="@国語" /></td> <td><xsl:value-of select="@数学" /></td> </tr> </xsl:for-each> </tbody> </table> </body> </html> </xsl:template> </xsl:stylesheet>
【参照】
XSLTの使い方・入門チュートリアル
data.xml が表示データの定義ファイルで、data.xsl が data.xml を HTML に変換する際の変換ルールを定義しています。<xsl:template match="/"> と </xsl:template> の間で HTML が定義されていて、<xsl:value-of> と <xsl:for-each> を使って表示データ(data.xml)のテキスト値や属性値を HTML に変換しています。
XML と XSL を使って HTML に変換(= XSL Transform)する方法はいくつかありますが、比較的簡単なマイクロソフト製コマンドラインツール msxsl.exe を使った例を紹介します、、が、このツールは便利ではあるのですが、かなり古いものらしく、マイクロソフトのサイトには存在しておらず、インターネットアーカイブ上でしか見つけることができませんでした。というわけでこちらからダウンロードしてください:
http://web.archive.org/web/20140812045521/http://www.microsoft.com/en-us/download/details.aspx?id=21714
ダウンロードできたら Windows 上でコマンドプロンプトを開き、data.xml , data.xsl の存在するフォルダに移動します。そして msxsl.exe にパスを通すか、data.xml, data.xsl と同じフォルダに msxsl.exe をコピーしてください。
準備ができたら以下を実行します:
> msxsl.exe data.xml data.xsl
msxsl.exe は2つのパラメータを指定して XSLT 処理を実行します。最初のパラメータが XML ファイルのパス、2つ目のパラメータが XSL ファイルのパスです。正しく実行できた場合は XSLT の実行結果が画面上に表示されます:

※このコマンドプロンプト画面ではシフト JIS でないと文字化けを起こしてしまいます。その理由もあって data.xml と data.xsl をシフト JIS で作ったという背景があるのでした。
個人的には XSLT 処理をプログラミング内で行うこともあるのですが、そこでうまくいかないケースに遭遇した場合、この msxsl.exe を使うとエラー発生時の内容や箇所をエラーメッセージとして表示してくれるので、主にデバッグ目的で今でもよく使っています。
この XSL(T) を使うことで、
・表示するデータは XML で、
・XML を XSL を使って変換した HTML を使って、
・HTML の見栄えは CSS で、
それぞれ役割分担して定義する、ということが可能になります。例えばデータベースから取り出した直後のデータは XML に近い形をしていることが多いので、そこから HTML を生成する際に XSL を使い、細かな見栄えは別途 CSS で定義する、という役割分担が、自分の理解の上でも腹落ちしやすいと考えています。
【ノーツのデータ構造に似ている】
ここまでに紹介してきた XML と XSL の関係というのが、HCL ノーツ/ドミノでいうところの「文書(document)」と「フォーム(form)」の関係に似ていると思っています。ノーツではデータそのものは文書として格納されていて、その見栄えは適用されるフォームによって定義されています。同じ文書でも適用さえるフォームによって見栄えが変わる点も含めて似ているのですが、加えてノーツのデータは DXL(Domino XML Language) という特殊な XML フォーマットでインポート/エクスポートできる機能があるので、XML/XSL との相性も悪くなかったりします。
まあ現実のノーツデータはそこまで単純ではありません。ノーツにはサブフォームや共有フィールドといった設計の再利用の仕組みがあったり、HTML とは異なる独特なリッチテキスト編集/保存機能があったり、細かな所では XSL のテンプレート名称に使ってよい文字とノーツのフォーム/サブフォーム名に使ってよい文字に違いがあったりして、単純に XML/XSL 対応ができるわけではなかったりします。
とはいえ、それでもノーツのデータをノーツ外で取り扱う(これ自体がすごくハードルの高いことだったりします)ことを目指そうとすると、 DXL にエクスポートした上で XML/XSL の仕組みをベースにすることでノーツ外でも取り扱いできるようにするための近道のようには感じています。どこまで実現できるかわからないのですが、個人的にそんなツールの開発を始めていて、いずれどこかで紹介できればと思っています。