IBM®
本文へジャンプ
    Japan [変更]    ご利用条件
 
 
検索範囲検索:    
    ホーム    製品    サービス & ソリューション    サポート & ダウンロード    マイアカウント    
skip to main content

developerWorks Japan  >  XML  >

XMLの論考: 第5回

XSLTを使ってDocBook文書を変換する方法

developerWorks
ページオプション

JavaScript を要するドキュメントオプションは表示されません

原文はこちら

原文はこちら


レベル: 初級

David Mertz, Ph.D (mertz@gnosis.cx), Author, Gnosis Software, Inc.

2000年 11月 01日

DocBook のサンプルをもとに、David Mertz 氏が、XSLT (Extensible Stylesheet Language Transformation) を使って、XML 文書を HTML に変換する方法を示します。その中では、XML 文書を変換する 4 つの代替手段を取り上げ、いくつかのオープン・ソース・ツールの使い心地にまで触れているわけですから、まさに勇気あるコラムニストです。サンプル・コードとしては、XSLT 文書の断片、シンプルな DocBook の 1 つの章を XSLT で記述した妥当な HTML 出力コード、簡単な XSLT ループ例が掲載されています。

XML 変換の世界にようこそ ! とはいっても、道のりは険しそうです。標準仕様は合体や改訂の繰り返し。ツールは未熟でバグだらけ。実装にも矛盾あり。どれを選ぼうにも、面食らうようなことばかりです。でも、うろたえるには及びません。このような迷宮から抜け出すための道が少なくとも 1 つあるのです。それをお示しいたしましょう。いずれにしても、結局は時間の問題です。たとえ思ったより時間が長くかかるとしても、事は必ず良い方向に向かっていくはずです。

目標

「XML の論考」の前回と前々回の記事では、私の学術論文を XML に変換するプロジェクトについて説明しました。具体的には、DocBook DTD に変換するわけですが、いずれにしても、読者の皆さんが自分自身の DocBook 文書を記述する出発点になったはずです。今回はそういう観点で話を進めましょう。

このコラムでは、きちんとした構造になっていて、整形式かつ妥当な DocBook XML 文書がすでに手元にあるという状態を前提にしましょう。確かにそのような文書がなければ話は始まらないわけですが、次にしなければならないのは、そのような文書をエンド・ユーザーにとってなじみ深い形式に変換するということです。HTML ページとか、PDF ファイルとか、印刷物のページとか、いずれにしても読者が実際に読めるかたちにするというわけです。これはまさに、私自身が古い文献の一部を DocBook に変換した時点で出くわした問題です。本稿では、そのときにどのようにして問題を解決したのかを示しましょう。

とりあえず、今の時点の主な目標は、HTML にうまく変換するということです。しかし、HTML の出力だけで済ませようとは思っていません。ほかにも、ささやかな目標がいくつかあります。まず、正確な出力をきちんと実現するために、やたらに手間をかけたり、新しい言語やテクニックについていろいろ学んだりしないということ、さらに、無償のツール、しかもプラットフォームを選ばないツールを使うということ、最後に、依存関係を最小限に抑えるということです。たとえすべてのツール類が無償で、プラットフォームを選ばないとしても、依存関係が複雑に入り組んでいると、それがどうしても足かせになります。基本的に私が理想としているのは、とりあえず実行すればいいという単体のツールです。もちろん、実行の信頼性は重要ですが、とにかくそのツールを実行しさえすれば、DocBook 文書が望みどおりのスタイルの HTML に変換されるというのが理想でしょう。大きな夢にすぎないでしょうか。でも、挑戦してみる価値はありそうです。




上に戻る


変換の方法

DocBook 文書 (というよりは、ほとんどすべての XML 文書) をエンド・ユーザーの形式に変換するための方法が、少なくとも 4 つあります。私自身も、自分のささやかなプロジェクトでその 4 つの方法を真剣に検討してみました。本稿では、その中の最後の方法だけを詳しく取り上げますが、変換処理を繰り返すようなプロジェクトを計画している場合は、4 つとも覚えておく価値があると思います。

  • 独自の変換コードを記述すること。 SAX や DOM のような基本的な XML メソッドのライブラリーを備えたプログラミング言語からスタートするのも、悪くはありません。しかし、独自のコードを記述すれば、たとえ基本的な構文解析がブラック・ボックスだと仮定しても、構文解析が済んだエレメントに対してはどんな処理でもできるわけです。突き詰めれば、これこそが最も柔軟で最も強力な方法です。もちろん、初期段階でも、保守段階でも、かなりの手間がかかるのは間違いなさそうです。
  • Cascading Stylesheet (CSS) を使って DocBook 文書を処理すること。 これは、1 つのアイディアです。確かに、出力様式を定めた仕様を文書構造のマークアップから完全に分離してしまい、クライアント・デバイス (ブラウザーなど) によって出力をきれいに処理できれば、たいへん便利なことではあります。今後そのような方向に進んでいくことは考えられますが、少なくとも現時点では、IE 5.5、Opera 4、最新の Mozilla 開発者リリースの一部などにしかそのためのサポートがないようです。出力処理をエンド・ユーザーにまかせてしまう段階には、まだまだ達していないのかもしれません。
  • Document Style Semantics and Specification Language (DSSSL) を使って、対象形式への変換を指定すること。 まずプラス面を取り上げれば、DocBook や他の形式のための DSSSL スタイルシートがすでに数多く存在しています。DSSSL は基本的に、学習の対象としては一人前の新しいプログラミング言語であり、使用の対象としては Lisp によく似た機能的な言語と言えます。DSSSL を活用するには、Jade や OpenJade といったツールから入る必要がありますが、いずれのツールもかなり複雑なので、そのためのいろいろなラッパー (SGML-tools Lite など) が開発されています。確かに、非常に効率的なシステムになり得るということは聞いていますが、実際に効率的なシステムを構築するには、システムのあらゆる種類の依存関係に対応し、あらゆる種類のツールやライブラリーをインストールする必要があるようです。私のシステムでも試してみたことがあるのですが、意図は悪くなかったものの、やる気が少し足りなかったのか、Jade 関連のツールをうまく機能させることができませんでした。考えてみれば、いろいろな人たちがそのようなシステムを毎日使っているわけですから、もう少しがんばれば、うまくいったのかもしれません。(もし、高速でシンプルなオールインワン・タイプの DSSSL プロセッサーをご存じの方がいれば、お知らせください。ぜひ使ってみたいと思います。) そのようなセットアップの難しさもさることながら、DSSSL は、XML のテクニックとは別の流れや考え方から出てきたような感じがあります。それとは対照的に、最後の方法は基本的に純粋な XML であり、W3C の公式な (ワーキング) 仕様から派生したものです。
  • eXtensible Stylesheet Language Transformations (XSLT) を使うこと。 XSLT は、ある意味では、XML 文書の 1 つのクラスを記述した仕様と言えます。要するに、XSLT スタイルシート自体が整形式の XML 文書なのです。この文書に、それぞれの好みの出力形式の "テンプレート" となるような特別な内容を追加していきます (このあたりの詳しい説明はまた後ほど)。少なくとも名目上この XSLT をサポートしているというツールは多数存在しています。W3C の "お墨付き" があるからと言うべきか、W3C の "お墨付き" があるにもかかわらずと言うべきかはともかく、私としても、XML 変換のテクノロジーはこの方向に進んでいくような予感がします。XSLT では、どんな対象形式に対する変換でも指定できるのですが、これまでの漠然とした印象からすると、XSLT を一番扱いやすいのは、対象形式が XML 形式の一種 (XHTML など) である場合だというのが、ほとんどの開発者の共通の感想のようです。



上に戻る


XSLT ツールの選択

参考文献には、各種 XSLT ツールの説明箇所へのリンクを載せておきました。そのうちのかなりのツールについては、私も実際に試してみましたが、中でも一番好みに合うのは Sablotron でした。これは、フリーのソフトウェアです (GNU)。プラットフォームも選びません。コマンド行から簡単に実行できる単体のツールでもあります。そして最後に一番肝心な点ですが、少なくとも私の簡単なテスト・ケースでは、正常に機能していたようです。

XSLT.com に列挙されているその他の XSLT ツールも、やはりフリーのソフトウェアです。ただし、そのほとんどは Java プログラムなので、いろいろな Java ライブラリーが必要になります。ユーザーたちは、かなりの Java ツールに対して好意的な評価をしているようです。選択肢として悪くはないでしょう。私の一押しの Sablotron は、コンパイル済みの C プログラム特有のスピードがあり、インストール方法も使用方法もいたって簡単です。

Norman Walsh 氏は、DocBook 用の完全な XSLT スタイルシートを作成しましたが、残念ながら、Sablotron は、そのスタイルシートを処理しようとするとクラッシュしてしまいます。XML Spy も、そのスタイルシートを使ったときに、妥当な DocBook 文書のどの部分にもマッチしませんでした。これはおそらく、Walsh 氏のスタイルシートというよりは、ツールの側の制約事項なのでしょう。他のツールでは、もう少しうまくいくかもしれません。いずれにしても、このような問題があったおかげで、独自の (やや完全さには欠ける) XSLT スタイルシートを開発できました。まさに、そのためのテクニックを示すという意味では、うってつけのスタイルシートになっています。

Sablotron の使い方は、非常に簡単です。基本は次のとおりです。


リスト 1: Sablotron の基本的な使い方
                
X:\mydocs> x:\sabl\bin\sabcmd mystyle.xsl mydoc.xml mydoc.html

この記述の意味は、mystyle.xsl の規則を使って、mydoc.xmlmydoc.html に変換するということです。必要であれば、パイプやリダイレクトも使えます。Sablotron のセットアップは、Sablotron のアーカイブを解凍するのと同じくらい簡単です (独自のプログラムから呼び出せるライブラリーも用意されていますが、まずはコマンド行ユーティリティーから始めるのがよいでしょう)。それぞれの環境に合わせて、パスやファイル名を変更してください。




上に戻る


XSLT 仕様の記述

XSLT の内容そのものについては、W3C の公式の勧告をお読みください (参考文献を参照)。本稿では、非公式の資料として、XSLT を実際に効果的に使うための詳細を取り上げたいと思います。

XML の論考 第 3 回」と「XML の論考 第 4 回」で作成した DocBook 文書 (chap5.xml) は、1 つの章 でした。あらゆる DocBook タグの中でも、ごく一部のタグしか使っていません。したがって、今の時点では、chap5.xml で実際に使っているタグだけをうまく処理するためのchapter.xsl ファイルがあれば、事が足ります。確かにささやかな出発点ではありますが、これこそが、今後の作業を進めていくための便利なベースになるのです。XSLT のオープンで拡張性の高い性質がまさに物を言うわけです。では、実際に見てみましょう。

最初に見るのは、chapter.xsl の骨組みです。名付けて、「DocBook の章を HTML に変換する方法」テンプレートです。


リスト 2: XSLT 文書の骨組み (empty.xsl)
                
<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns="http://www.w3.org/TR/xhtml1/strict">
 <xsl:output method="html" indent="yes" encoding="UTF-8"/>
</xsl:stylesheet>

お気づきのとおり、chapter.xsl は、整形式の XML ファイルです。さらに、これから見ていきますが、<xsl:*> というパターンが、XSLT 文書の多くのタグの名前になります。実際のところ、命令系のタグはすべてそのようなスタイルになります。XML によく似た形式 (HTML など) に変換するときは、ほかにもいろいろなタグを使いますが、その種のタグは、対象形式のタグであり、必ず<xsl:*> エレメントの中に指定します。

基本的に、名前空間の属性 (xmlns:xslxmlns) については、上のコード例のとおりに指定する必要があります。出力 (output) の行についても、そのまま使うことが多いかもしれません。ただし、xml メソッドやtext メソッドも使えます。

上記の XSLT ファイルは、処理用のテンプレートとしては申し分ありませんが、必ずしも期待どおりの結果が出るとは限りません。たとえば、出力の仕様が抜けているので、実際には何も出力されないと思うでしょうか。しかし、そうではありません。上記のスタイルシートの場合は、すべてのテキスト・ノードを取り込んで、プレーンな ASCII 版の章を出力します。本当に出力をなし にしたいのであれば、リスト 3 のような XSLT 文書にするとよいでしょう。


リスト 3: 出力なしの XSLT 文書 (null.xsl)
                
<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns="http://www.w3.org/TR/xhtml1/strict">
 <xsl:output method="html" indent="yes" encoding="UTF-8"/>
 <xsl:template match="*">
 </xsl:template>
</xsl:stylesheet>

この出力なしのスタイルシートは、実用的な変換の 1 つの方向性を示しています。本来のスタイルシートというものは、マッチングを試みるパターン・セットの記述であって、出力内容を指定するテンプレートは、各<xsl:template> エレメントの中に指定します。このサンプルにあるように、"*" を指定した場合は、あらゆるパターンがマッチします。ここではたまたまテンプレートの内部で何も実行 しませんが、それでも、ソースの XML/DocBook 文書内にマッチするエレメントがないかどうかを探し出そうとするわけです。




上に戻る


下位構造に踏み込むマッチング

XSLT テンプレートの威力は、基本的にマッチング機能を拡張できるという点にあります。要するに、1 つのエレメントがマッチした場合、XSLT は、そのエレメントの子エレメントにマッチング機能を拡張するわけです。先ほどの出力なしのスタイルシートをベースにして、少し意味のあるスタイルシートを作成してみましょう。子エレメントへの拡張を指定する重要なタグは、<xsl:apply-templates> です。一般に、すべてのテンプレートには、本体のどこかにこのタグが組み込まれています。


リスト 4: 最小限の章の XSLT 文書 (minimal.xsl)
                
<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns="http://www.w3.org/TR/xhtml1/strict">
 <xsl:output method="html" indent="yes" encoding="UTF-8"/>
 <xsl:template match="chapter">
 ----- Start of Chapter -----
 <xsl:apply-templates/>
 </xsl:template>
 <xsl:template match="*">
 ##### Unmatched Element in Source #####
 </xsl:template>
</xsl:stylesheet>

このスタイルシートと DocBook の章を使って XSLT プロセッサーを実行すると、次のような出力が得られます。


リスト 5: スタイルシートと DocBook の章を使って XSLT プロセッサーを実行した場合の出力
                
----- Start of Chapter -----
##### Unmatched Element in Source #####
##### Unmatched Element in Source #####
##### Unmatched Element in Source #####

この出力は実際に使い物になるわけではありませんが、スタイルシートの機能を見るという意味では役に立ちます。章のルートエレメントは、<chapter> タグです。このスタイルシートは、<chapter> タグがマッチした時点で、「 - - - - - Start of Chapter - - - - - 」を出力します。<chapter> エレメントの内部には、いろいろな子エレメントが指定されています。それぞれの子エレメントは、章 (chapter) 以外の名前が付いているので、"*" テンプレートのマッチングに渡されることになります。

独自の XSLT スタイルシートを作成する場合にも、上記のようにマッチングから漏れたエレメントのための分かりやすいフラグを組み込んでおくと、どんなテンプレートを作成する必要があるのかが、一目で分かるようになります。リスト 6 は、実際のテンプレートをいくつか組み込んだスタイルシートです。


リスト 6: 妥当な HTML 出力用の XSLT 文書
                
<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns="http://www.w3.org/TR/xhtml1/strict">
 <xsl:output method="html" indent="yes" encoding="UTF-8"/>
 <xsl:template match="chapter">
 <html>
 <head>
 <title>
 <xsl:value-of select="title"/>
 </title>
 </head>
 <body>
 <xsl:apply-templates/>
 </body>
 </html>
 </xsl:template>
 <xsl:template match="chapter/title">
 <hr></hr>
 <h1><xsl:apply-templates/></h1>
 </xsl:template>
 <xsl:template match="para">
 <p><xsl:apply-templates/></p>
 </xsl:template>

この HTML 出力用の文書では、XSLT スタイルシートの現実的な特色がいくつか見られます。まず、chapter テンプレート・マッチ (template match) によって、生成したいと思っている HTML 文書のレイアウトを指定します。テンプレート・マッチの内部の HTML タグには特別なものは何もありません。ただ指定したテキストが出力に表示されるというだけのことです。HTML の<title> エレメントの中では、<xsl:value-of> 命令を使って、DocBook の<chapter> 内で必要なtitle 子エレメントを組み込んでいます。HTML の<body> エレメントの中では、他のテンプレートに制御を渡すわけですが、DocBook 全体で使用するテンプレートは、おそらくかなりの数に上るでしょう。

chapter の次のテンプレートはchapter/title です。この場合は、<chapter> の内部に直接組み込まれている<title> エレメントがマッチします。もちろん、単にtitle がマッチするような指定も可能です。その場合は、ソース文書内のあらゆる<title> エレメントに対して同じ出力形式が指定されることになります。しかし、私としては、章の表題 (title) は、sect1 の表題やsect2 の表題などとは違う形式にしたいと思いました。そのような他のケースの表題のために、このサンプルではpara を指定しています (ただし、para は、マッチングから漏れたタグの内部にしか指定できないので、実際にマッチすることはありません)。さらに、おまけのようなものですが、依然として "*" というテンプレート・マッチも使っています。要するに、出力を見れば分かるとおり、このスタイルシートはまだ完全ではないのです。




上に戻る


子エレメントの反復

下位構造に踏み込むテンプレートのマッチングは、XSLT で駆使できるいろいろなテクニックの 1 つにすぎません。ほかにも、条件付きの出力、ソート、ソースの属性の引き抜き、子エレメントのループといったテクニックがあります。今回は、リスト 7 のような簡単なループ例だけを見てみることにしましょう。


リスト 7: 子エレメントのループを指定した XSLT テンプレート
                
<xsl:template match="simplelist"> <ul>
 <xsl:for-each select="member">
 <li><xsl:apply-templates/></li>
 </xsl:for-each> </ul></xsl:template>

ここでは、simplelist 内にすべての子エレメントに踏み込むのではなく、子エレメントをすべての<member> エレメントに限定しています。<xsl:for-each> の働きは、入れ子のテンプレートのようでもあり、プログラミング言語のループ構造のようでもあります。<xsl:for-each> エレメントの内容は、select 属性にマッチするすべての子エレメントの出力に対して適用されます。このループの中では、現在の<member> エレメントの内容が、ループ内の<xsl:apply-templates/> タグにまで踏み込むアクティブ・ノードになります。要するに、リスト内のあらゆるエレメントにはさらに内部のマークアップが存在することがあるので、そのようなエレメントの形式設定情報をそれぞれの適切なテンプレートに渡すというわけです (テキスト・ノードの場合は、そのままの形式で出力されます)。




上に戻る


さらなる飛躍

今回の資料は、XSLT の表面をなぞっただけにすぎません。とはいっても、スタイルシートとはどんなものか、変換とは何なのかをある程度示せたのではないでしょうか。参考文献には、関連資料を数多く載せています。特に、本稿のアーカイブ・ファイルには、もっと詳細な XML サンプルや XSLT サンプルがあります。ぜひお役立てください。次回以降の記事も、どうぞお見逃しなく。XSLT についてさらにいろいろな角度から取り上げる予定です。



参考文献

  • Extensible Stylesheet Language (XSL) の詳しい仕様と説明については、World Wide Web コンソーシアム (W3C) のXSL ホーム・ページをご覧ください。

  • World Wide Web コンソーシアム (W3C) のXSLT 勧告 1.0 には、XML の名前空間メカニズムの概要が記述されています。XSL Transformations (XSLT) の構文とセマンティクスの定義についても、詳しく説明されています。

  • XSLT.com には、多彩な XSLT ツールに関する調査の要約が掲載されています。

  • Joe Brockmeier 氏の「A gentle guide to DocBook」は、SGML-tools Lite の使い方に関する入門資料として好適です。これは、DocBook 文書を XSLT によって変換する方法とは違い、DSSSL を活用した方法のためのツールです。

  • James Clark 氏のDocument Style Semantics and Specification Language (DSSSL) のページには、DSSSL の詳細を知るための優れた資料が用意されています。

  • IBM の alphaWorks が提供しているXeena XML Editor (90 日間の無償ライセンス) は、妥当な DTD に基づく妥当な XML 文書を編集するための汎用 Java アプリケーションです。

  • 私の XML Spy の製品レビューについては、webreview.com をご覧ください。

  • 商用 XML エディターについては、以下のサイトをチェックしてください。
  • XML 文書を妥当性を検査する場合は、Scholarly Technology Group のWeb ベースの XML 妥当性検査フォーム (ソース公開、無償ライセンス) を活用できます。

  • DocBook の詳細を説明した入門資料としては、DocBook: The Definitive Guide (Norman Walsh & Leonard Muellner 共著、O'Reilly、Cambridge、MA 1999 年) が最適です。この本の電子ブック版もあります。

  • Organization for the Advancement of Structured Information Standards(OASIS) は、「XML や SGML などの公開規格に基づいて、だれもが共同で活用できる業界標準仕様を作成する」ための非営利の国際コンソーシアムです。

  • 本稿で使用 (言及) したファイルをダウンロードできます。

  • 私の過去のコラムもご覧ください。


著者について

Photo of David Mertz

David Mertz氏は多くの分野で活躍しています。ソフトウェア開発や、それについて著述もしています。その他、学術政策理念について分野を問わず、関係する雑誌に記事も書いています。かなり以前には、超限集合論、ロジック、モデル理論などを研究していました。その後、労働組合組織者として活動していました。そして、David Mertz氏自身は人生の半ばにもまだ達していないと思っているので、これから何かほかの仕事をするかもしれません。




記事の評価


サイト改善のため、ご意見をお寄せください。こちらのフォームからお願いいたします。



 


 


不充分・不完全である大変素晴らしい
 


この記事を共有する

del.icio.us del.icio.us newsing newsing FC2ブックマーク FC2ブックマーク
Choix! Choix! ニフティクリップ ニフティクリップ Yahoo!ブックマーク Yahoo!ブックマーク
MM/memo MM/memo CZブックマーク CZブックマーク livedoorクリップ livedoorクリップ
はてなブックマーク はてなブックマーク Buzzurl(バザール) Buzzurl(バザール)




上に戻る


    日本IBMについて プライバシー お問い合わせ