PostgreSQLでXMLを処理してみよう!(第4回)(1)
第4回XSLTの基礎
-XMLデータ変換を行うためのPostgreSQLのXSLT機能紹介-
響 楽人
はじめに
本連載では、これまでXMLの基礎、XPathの利用法を取り上げてきました。第4回目となる今回はXSLTについて紹介します。(XSLTはXPathの理解も必要としますので、第2回、第3回の記事も合わせてご覧ください。)
XSLTは、XMLからXMLへの変換指定を記述する規格で、HTMLへの変換も行うことができます。この記事の題材としては、第3回で使った例を用い、通常のRDBデータとXML型のデータを両方含むハイブリッドなデータベースからXMLデータを取り出し、それをPostgreSQLのXSLT機能を使ってHTMLへ変換してブラウザで表示できる形にするというシナリオを考えます。
現在のPostgreSQLでは、XSLT機能は追加モジュールとして提供されていますので、若干の設定作業が必要となります。そこで、最初にXSLTについて簡単に紹介した後、XSLT機能を使えるようにする操作を説明します。その後、XSLTを使った具体的な利用例を示します。仕様が膨大なXSLTの書き方についてはこの記事では説明し切れるものではないので、具体例として示したXSLTの書き方の説明を最後に一通り行いますが、詳しくは一般の参考書に譲ることとします。
XSLTの概要
XSLT (XSL Transformations) とは、XMLデータの構造変換を行う指定方法を定めたW3Cの規格であり、企業・団体間で使用する要素名や構造が違うなど、異なるフォーマットのXMLデータ交換を行う際に必要なXMLデータ構造変換に使うことができます。前述のようにXML→XMLだけでなく、XMLとしても記述可能なHTMLへの変換にも使えるので、XMLデータをブラウザ表示する目的で使うことも広く行われています。今回の利用例ではこのHTMLへの変換を示します。
まずXSLTで使う用語を説明しましょう。XSLTでは、変換前のXMLデータの構造を「ソースツリー(source tree)」、変換後のXMLデータの構造を「結果ツリー(result tree)」と呼びます。「スタイルシート(Stylesheet)」とは、ソースツリーからどんな結果ツリーを生成するかを具体的に記述した指定情報です。「スタイルシート」という言葉を聞くと、表示の見栄えを指定する情報のように聞こえます。これは、XSLTが、元々XMLデータの表示スタイルの指定言語であるXSL(Extensible Stylesheet Language)の機能の一部として開発された変換指定であり、それを汎用的なXML変換技術として独立させたことに由来しています。XSLTがXSL Transformationの略称であることもこのことを表しています。
「XSLTプロセッサ」とは、XSLTスタイルシートを解釈して構造変換を実行するプログラムで、PostgreSQLの場合、xml2という追加モジュールにxslt_process関数として含まれています。
ソースツリー、結果ツリー、XSLTスタイルシート、XSLTプロセッサの関係を図に表すと以下のようになります。
PostgreSQLでXSLT機能を使えるよう設定する~xml2モジュールの準備
PostgreSQLでXSLT処理を行う場合、xml2モジュールに含まれているxslt_process関数を利用しますが、このxml2モジュールは標準ではインストールされませんので、使う前に設定作業が必要です。これまで使ってきたtestdbデータベースに対してxml2モジュールを使えるようにするWindows XPでのインストール手順は以下の通りです。このインストールは、PostgreSQLのスーパーユーザで行います。
(1)スタートメニューからPostgreSQL8.3用のコマンドプロンプトを開き、以下のコマンドでxml2の導入スクリプトであるpgxml.sqlを実行します。(pgxml.sqlを含むファイルパスについては、ご自分のインストールフォルダを確かめて入力してください。また、ここでは連載第1回で作成し、それ以来使っているtestdbデータベースが作成されていることが前提です。)
-
psql -U postgres -d testdb -f "C:\Program Files\PostgreSQL\8.3\share\contrib\pgxml.sql"
(2)パスワードを入力します。(パスワードは非表示)
-
Password for user postgres:
(3)以下のように「CREATE FUNCTION」が14行表示されたらxslt_process関数などが使えるようになったということでインストール成功です。
-
SET CREATE FUNCTION CREATE FUNCTION CREATE FUNCTION CREATE FUNCTION CREATE FUNCTION CREATE FUNCTION CREATE FUNCTION CREATE FUNCTION CREATE FUNCTION CREATE FUNCTION CREATE FUNCTION CREATE FUNCTION CREATE FUNCTION CREATE FUNCTION
PostgreSQL上でのXSLT処理の実際
XSLTプロセッサであるxslt_process関数が使えるようになったので、早速PostgreSQLに格納されているXMLデータをスタイルシートで変換してみましょう。変換対象となるXMLデータは、第3回でも使用したmeiboテーブルのwork_history列にあるデータとします。それを変換してHTMLを生成するために用意したXSLTスタイルシートは、以下の通りです。
-
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="html"/> <xsl:template match="/"> <html><xsl:apply-templates/></html> </xsl:template> <xsl:template match="work-record"> <h1>職務経歴一覧表</h1> <table frame="border" border="5" width="70%"> <tr><th>始</th><th>至</th><th>内容</th><th>役割</th></tr> <xsl:for-each select="career"> <tr> <td width="20%"><xsl:value-of select="period/start"/></td> <td width="20%"><xsl:value-of select="period/end"/></td> <td width="40%"><xsl:value-of select="content"/></td> <td width="20%"><xsl:value-of select="role"/></td> </tr> </xsl:for-each> </table> </xsl:template> </xsl:stylesheet>
この指定の意味については次節「スタイルシートの構成と書き方」で説明します。
まずはPostgreSQLがRDBの照会結果をXSLTを使って変換できることを確認しましょう。
事前準備として前述のスタイルシートをファイル名を「career_table.xsl」としてC:\dataフォルダに保存しておきましょう。直接スタイルシートの内容をコマンド・プロンプトの画面で入力することもできますが、通常非常に長い指定となるので、一般にそれは現実的ではないでしょう。そこで、スタイルシートをファイルから読み込みます。なお、第3回で使用したcopyコマンドのときと同様、このファイルにもpostgresユーザーのアクセス許可が設定されている必要があります。(第3回記事の「RDBとXMLのハイブリッドなクエリー」の節の最後の方で画面キャプチャで説明している個所を参照してください。)
まずは、通常通り、処理対象となるデータベースtestdbにpsqlで接続します。そしてtestdbのmeiboテーブルから“鈴木花子”の職務経歴一覧を取り出し、それをXSLTスタイルシートに従って変換します。
meiboテーブルから取り出した変換前の状態を確認するため、XMLデータを普通のSELECT文で取り出すと、結果は以下のようなXMLデータとなります。
-
testdb=# SELECT work_history::text FROM meibo WHERE name = '鈴木花子'; work_history ------------------------------------------------------------------------ <work-record> <career> <period> <start>2003-04-01</start> <end>2003-06-30</end> </period> <content>大手コンテンツプロバイダー向け顧客管理システム開発</content> <role>プロジェクトメンバー</role> </career> <career> <period> <start>2003-07-01</start> <end/> </period> <content>SCM導入コンサルタント</content> <role>アシスタント</role> </career> </work-record> (1 row)
テキスト情報になっているとは言え、XMLのままでは情報を十分に把握できませんし、XMLには見る必要のない情報まで入っているかもしれません。必要とする情報だけを人間に見やすく表示するため、上記のXMLデータを元データ(XSLT処理モデルのソースツリー)として職務経歴に相当する情報を整形してHTMLに変換するというのが今回の作業です。そして、照会結果データの変換を行うのがxml2モジュールの提供するxslt_process関数です。
xslt_process関数
スタイルシートを読み込んで変換するのに使うxslt_process関数の構文はxslt_process(document, stylesheet)です。ここでdocumentは元となるXML文書であり、stylesheetはスタイルシートのことです。そしてxslt_process関数では、document、stylesheetのいずれもテキスト型となっています。そこで、XML型のデータを指定する場合は、::text を使って一旦テキスト型へ変換します。
-
xslt_process(work_history::text, 'C:/data/career_table.xsl')
xslt_process関数は、返される結果もテキスト型です。
'鈴木花子'さんに関してmeiboテーブルから取り出した先ほどのXMLデータにスタイルシートを適用するSELECT文は以下のようになります。
- SELECT文:
-
SELECT xslt_process(work_history::text, 'C:/data/career_table.xsl') FROM meibo WHERE name = '鈴木花子';
実行結果は次の通りです。XSLTによってHTMLに変換されていることが分かります。
- 結果:
-
xslt_process ------------------------------------------------------------- <html> <h1>職務経歴一覧表</h1> <table frame="border" border="5" width="70%"> <tr> <th>始</th> <th>至</th> <th>内容</th> <th>役割</th> </tr> <tr> <td width="20%">2003-04-01</td> <td width="20%">2003-06-30</td> <td width="40%">大手コンテンツプロバイダー向け顧客管理システム開発</td> <td width="20%">プロジェクトメンバー</td> </tr> <tr> <td width="20%">2003-07-01</td> <td width="20%"></td> <td width="40%">SCM導入コンサルタント</td> <td width="20%">アシスタント</td> </tr> </table> </html> (1 row)
さて、変換結果のHTMLを見てみるとxslt_processというタイトル(ヘッダ)や、点線、(1 row)(フッタ)などHTMLとしては不要なデータが含まれています。そこで、純粋にHTML部分だけを得るため、psqlのオプションで tuples_only を指定します。これは、ヘッダやフッタを表示せずに、テーブルの実データのみを表示するためのオプションです。この指定を行うには \pset tuples_only、あるいは \t と入力します。(このコマンドを再度使うと照会結果にヘッダやフッタが表示されるモードに変わります。つまり、これらのコマンドはヘッダ/フッタの表示の有無の切り替えコマンドです)
- ヘッダ/フッタ非表示オプションの指定法:
-
testdb=# \t Showing only tuples.
(非表示モードを解除するときはもう一度 \t を実行します。)
この状態で先ほどのSELECT文を実行した結果です。
-
<html> <h1>職務経歴一覧表</h1> <table frame="border" border="5" width="70%"> <tr> <th>始</th> <th>至</th> <th>内容</th> <th>役割</th> </tr> <tr> <td width="20%">2003-04-01</td> <td width="20%">2003-06-30</td> <td width="40%">大手コンテンツプロバイダー向け顧客管理システム開発</td> <td width="20%">プロジェクトメンバー</td> </tr> <tr> <td width="20%">2003-07-01</td> <td width="20%"></td> <td width="40%">SCM導入コンサルタント</td> <td width="20%">アシスタント</td> </tr> </table> </html>
これで、HTMLとして使えるデータが得られることが分かったので、この結果を直接ファイルに書き出すことにしましょう。これには \o コマンドを使います。これは直後に指定したファイルにSELECT文の実行結果を出力するというコマンドです。
- 照会結果のファイルへの出力指定:
-
\o 'C:/data/result001.html'
この状態で、HTMLファイルへの書き出しを含む以下のSELECT文を実行します。
- SELECT文:
-
SELECT xslt_process(work_history::text, 'C:/data/career_table.xsl') FROM meibo WHERE name = '鈴木花子';
これで、照会結果のXMLを変換したHTMLデータはresult001.html に格納されます。これをブラウザで開くと以下のように表示されます。
特定の人の職務経歴を取り出して、HTMLによって人が読める状態になりました。
同じことは、データベースからXMLを取り出した後、一般のXLSTプロセッサを使ってもできます。しかし、PostgreSQLの場合、これらの工程をxslt_process関数を使ってデータベース照会と同時に変換が行えるのです。これは大変便利な機能です。
ところで、先ほどの \o による出力先ファイルの指定は、その後の照会結果すべてに有効です。つまり、この後別のSELECT文を実行するとその結果も result001.html に追加されてしまいます。このためファイル指定なしの \o コマンドを実行し、元の画面出力に戻しておきましょう。