この資料では XSLT 言語の基礎と,XML 文書からデータの検索や抽出を行うための方法を学ぶ。
XML 文書をどのように変換するかを書いた XSLT スタイルシートを作り, XML 文書と XSLT スタイルシートを XSLT プロセッサで処理して結果を得る。
図 2.1の左側に XML 文書の一例を示す。 この文書のルート要素は ref であり,ref の内容は文字データの Reference,および book や web 等の要素である。
XSLT では,XML 文書を木 (tree) 構造を持つデータとして扱う。 図 2.1の右側は, 左側の XML 文書を XSLT のデータモデル (木) として描画したものである。 この木における / や ref, #TEXT などをノード (node) と呼ぶ 2。
この木には,次に示す 4 種類のノードがある 3。
XML 文書をモデル化した木からノードを指定する記述がロケーションパス (location path) である。 この資料で扱うのはロケーションパスの省略記法のみであり, この場合,ロケーションパスの基本的な記述法はディレクトリやファイルのパス名と同じである。
なお,ロケーションパスは XPath (XML Path Language) という規格で定められている 4。
例:/ref/web/title
例:/ref/book/@isbn
ノードセットの指定には,次のようなロケーションパスを用いることもできる。
/ref/* ref ノードのすべての子要素ノード /ref/book/@* book ノードのすべての子属性ノード //title ルートノードの子孫であるすべての title 要素ノード /ref//title ref ノードの子孫の中のすべての title 要素ノード /ref/book |
/ref/webref ノードの子要素ノード book と web をあわせたノードセット
/ref/book[2] 2 番目の book 要素ノード /ref/book[@isbn='1111'] isbn 属性が 1111 である book 要素ノード /ref/book[author] author 要素ノードを子に持つ book 要素ノード /ref/book[2]/title 2 番目の book ノードの子である title 要素ノード
相対ロケーションパスでは,基点となるノードを . (ドット)で表し,親ノードを .. (ドット二つ)で表す。
第 2.1 節の木において,仮りに web を基点とすれば,相対ロケーションパスの例は次のとおりとなる。
web の子ノードの title は ./title または title
ref は .. であり,/ は ../..
isbn は ../book/@isbn
相対ロケーションパスの実際の基点は, XSLT では,カレントノード (current node) と呼ばれる, 現在処理中のノードである。 (= ドット . で表されるノード)となる 7。 カレントノードについては,3.1 で説明する。
なお,相対ロケーションパスでも,第 2.2.3 節で紹介したノードの絞り込みが可能である。
XSLT スタイルシートは,XML 文書をどのような形に変換するかを,XSLT で記したものである 8。 なお,以下では XSLT スタイルシートを,単にスタイルシートと呼ぶことがある。
次の例は,変換対象となる XML 文書から,
XML 宣言やタグ等を除いた文字データ部分をすべて出力するスタイルシートである。
<?xml version="1.0" encoding="UTF-8" ?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text" encoding="UTF-8" /> <xsl:template match="/"> <xsl:value-of select="/" /> </xsl:template> </xsl:stylesheet>
XSLT スタイルシート自体も整形式の XML 文書なので, スタイルシートにも前回資料にある XML の用語(XML 宣言や要素,属性等) や規則が当てはまる。 加えて,XSLT 独自の規則等がある。 上記スタイルシートにおける,各記述の意味や役割を以下に記す。
XSLT スタイルシートには xsl:sytlesheet 要素が必要である。 この要素の内容 (この次の行から終了タグ </xsl:stylesheet> の前まで) は,XSLT の規則に従って記述しなければならず, ここに記述される xsl: で始まる名前の要素には, XSLT に固有の意味や役割がある。
xsl:stylesheet 要素の子要素を,XSLT の用語でトップレベル要素 (top-level element) という。 トップレベル要素として記述できる要素は限定されており, この資料では xsl:output と xsl:template 要素のみを用いる。
xsl:output 要素は,変換結果の出力形式を定める。 ここでは出力形式を text 形式9, 出力の文字コードを UTF-8 としている。
xsl:template 要素は,変換元の XML 文書の中の
1. を指定するのが xsl:template 要素の match 属性であり, 属性値 / は変換元の XML 文書全体を指している。
2. は xsl:template 要素の内容として記述する。 この記述をテンプレートという。
テンプレートには,XSLT により意味が定められている要素や, その他の出力したい文字データ等を書いていく。
テンプレート内に記述した文字データは,基本的にはそのまま出力されるが, 空白文字(ブランクや改行)のみからなる文字データは出力されない。 出力の細かな振る舞いは xsl:output 要素の method 属性の指定によって変わる。
なお, 一つのスタイルシート内に match 属性値の異なる xsl:template 要素を複数記述することが可能であるが, 扱いが煩雑となるため, この資料で扱うスタイルシートでは, 属性 match="/" の xsl:template 要素を一つだけ記述することとする。
xsl:value-of 要素を用いると,変換対象となる XML 文書から, select 属性で指定したものを取り出すことができる。
この要素の使い方は後述するが, select="/" を指定すれば, xsl:value-of 要素は XML 文書全体から文字データ部分をすべて取り出す。
これを xsl:template 要素の内容として記述することで,XML 文書の文 字データ部分をすべて出力するスタイルシートを作成したことになる。
XSLT スタイルシートでは,ロケーションパスをテンプレート内で使うが, その際の (初期の) カレントノードは xsl:template 要素の match 属性によって決まる。 例えば,<xsl:template match="/"> で始まるテンプレート内の初期カレントノードはルートノードである。 従って, このテンプレートでは / と . は等価であり, <xsl:value-of select="/" /> と <xsl:value-of select="." /> の出力は同じである。
テンプレート内にカレントノードを変更する XSLT の要素があれば, その中ではカレントノードに応じて相対ロケーションパスの基点が変わる 10。
これは,要素ノードに対応する XML 文書の要素から,タグ <...> を除いたものに相当する
<xsl:value-of select="expression" />
expression として,単一のノードに対応するロケーションパスを指定すれば, xsl:value-of はそのノードの文字列値を XML 文書から取り出す。 複数のノード(ノードセット)に対応するロケーションパスを指定すれば, ノードセット中の最初のノードの文字列値のみを取り出す。
expression には,次の例のように,XSLT の関数も書ける。
<xsl:value-of select="count(/ref/book)" />関数 count は,引数に与えられたノードセットの個数を返すものであり, この xsl:value-of 要素を含むスタイルシートを第 2.1節の XML 文書に適用すれば, /ref/book のノード数である 2 が出力される。
ここでは,XSLT プロセッサとして xsltproc コマンドを用いる。 実行の書式は次のとおり。
xsltproc [option] stylesheet file ...ここで, stylesheet と file は,各々, XSLT スタイルシートと XML 文書の入ったファイルの名前である。 例えば,
xsltproc /pub/db/xml/all.xsl /pub/db/xml/ref.xmlは, XSLT スタイルシート /pub/db/xml/all.xsl の内容に則って XML 文書 /pub/db/xml/ref.xml を変換し, 結果を標準出力(画面)に出力する。 結果をファイルに入れたければ, リダイレクト (
>
file) を使えばよい。
以下の問題では,xsltproc コマンドを使って, 指定された XML 文書に XSLT スタイルシートを適用し, 処理しなさい。 今回の練習問題では, 出力における空白や改行の乱れは無視してよい。
/ref/web/title, /ref/book/@isbn, /ref/book, /ref/book[2], /ref/book[@isbn='1111'], /ref/book[author], /ref/book[2]/title, ./ref/web/titleを select 属性値とする xsl:value-of 要素を記述して (一つのスタイルシートに追加してよい), 第 2.1 節の XML 文書 (/pub/db/xml/data_model.xml) を処理し, 各出力が得られる理由を確認しなさい。