XSLTを学ぶ (1) XMLのツリーモデルとXPath/XSLTのツリーモデルではルートの意味が違う

先月『スタイルシート開発の基礎』[1]という本を出版しました。この本は、副題に「XMLとFOで簡単な本を作ってみよう」とあるとおりXSLTの実践学習本です。現在、弊社の社内でも、初心者が集まって、この本を使ってXSLTの学習をはじめたところです[2]。私もメンバーの一人です。

『スタイルシート開発の基礎』のはじめにには「XSLT/XPathの知識はない」人が本書の対象とあります。私もXSLTを本格的に学ぶのは初めてですので、本書の想定読者にあてはまりそうです。

素直に読めば、この本だけで理解できるのかもしれませんが、折角ですので、他の参考資料や仕様書をにらみ合わせて楽しみながらお勉強。そこで、折角学んだことを整理して、紹介したいと思います。すでにご存知の方には、初歩的なお話と思いますが、『スタイルシート開発の基礎』の補足として役立てていただけるかもしれません。

資料としては次を見ています。

・『XSLTバイブル』(Michael Kay著、インプレス社、2002年1月発行)
・XSL Transformations (XSLT) Version 1.0(W3C Recommendation 16 November 1999)[3]
・XML Path Language (XPath) Version 1.0(W3C Recommendation 16 November 1999, revised 7 September 2015)[4]

さて、今回勉強し始めて知ったのですが、整形式XMLのツリーモデルとXSLT/XPathのツリーモデルはまったく違うんですね。

XML1.0では、整形式XML文書はルートが文書の実体ツリーの起点であり、XMLプロセサはルートから処理を始めます。さらに見ますと、ルートまたは文書要素と呼ばれる要素が唯一あるとされています。ルート要素は他の要素の内容になりません(つまり親を持ちません)が、他の要素は親を持ちます[5]。整形式XML文書はルート要素(文書要素)を起点とする要素のツリー構造になります。

しかし、XPathのデータモデルは、ノードという概念が中核です。ノードの種類として次の7つがあります。
・ルートノード(root nodes)
・要素ノード(element nodes)
・テキストノード(text nodes)
・属性ノード(attribute nodes)
・名前空間ノード(namespace nodes)
・処理命令ノード(processing instruction nodes)
・コメントノード(comment nodes)

原文でroot nodesと複数形になっているのが気になりますが、XPath仕様の5.1 ルートノード(Root Node)には、「ルートノードはツリーのルートであり」、「文書要素ノードはルートノードの子である」、「ルートノードの子供として、処理命令、処理命令のためのコメント、プロローグの中の文書要素の後のコメントノードがある。」とあります。

また、XSLT仕様の3 データモデル(Data Model)を見ますと、XSLTでは、ソース文書、スタイルシート、結果文書に同じデータモデルを使います。それらはXPathのデータモデルを基本として、少しだけ変更したものです。

・整形式のソースXML文書を読み込んでソースツリーを構築するときは、ルートノードの下にテキストノードはなく、唯一の要素ノードを子として持ちます。また、DOMなどの他の方法でソースツリーを作るときは、ソースツリーに対する制約は結果ツリー同様に緩められます。

・文書スタイルシートのツリーを構築するときは処理命令とコメントノードを無視します。

・結果ツリーでは、ルートノードへの制約が緩められており、子供として要素ノードを含む、任意のノードの系列をもつことができます。これにより、整形式XMLでない出力を作ることができます。

ですので、たぶん、XSLTでは整形式でないようなソースXMLでも処理できそうです[5]

[1] 『スタイルシート開発の基礎』
[2] アマゾンPODの便利な利用法
[3] XSL Transformations (XSLT) Version 1.0
[4] XML Path Language (XPath) Version 1.0
[5] Extensible Markup Language (XML) 1.0 (Fifth Edition) 2 Documents
[6] 余談です。『スタイルシート開発の基礎』の著者(神様)に、Michael Kayさんの本にそんなことが書いてある、と話しましたら、仕様書のどこに書いてあるかを示せ! と言われました。それは、3.1 Root Node Childrenの二つ目の段落の後半のセンテンスにあります。

次回:
XSLTを学ぶ(2)ノードツリーとノードの親子、子孫関係