| 今回はXML関連規格解説シリーズ第1弾としてXPath を取り上げます。これはXML の構造変換を行うXSLT の中で使用されたり、リンク指定で使用されるXPointerで使用されたりと、様々な分野で応用される大事な規格です。このシリーズでは、それぞれの規格のエッセンスを1話完結でまとめます。 |
XSLT は、XML データの構造をツリーと見るならば、ツリーからXML ツリーへの変換指定を行うための規格です。これを使ってたとえばマイクロソフト社のIEには、XML をHTML に変換して表示させる仕組みが組み込まれていることは皆さんもご存知でしょう。変換元のツリーをソースツリー(source tree)と呼び、変換先のツリーを結果ツリー (result tree) と呼びます。

図1
ところで、このXSLT による指定を行うには、変換元のソースツリーのノードを特定する必要があります。これを担当するのがXPathです。XPath は、「XMLPath Language(XPath) Version1.0」として1999年11月16日にW3C勧告となった規格です。
XPath によるノード特定の方法の基本はロケーションパス(location path)と呼ばれるものを使います。これはツリーをたどることによってノードを特定するものです。ロケーションパスでは、この「たどり」の起点に関して、ツリーのルートからたどるものと、何らかの現在位置(ノード)からたどるという違いによって次の2つに分類されています。
● 絶対ロケーションパス
● 相対ロケーションパス
絶対ロケーションパスを使えば、変換処理において現在位置がどこであろうとソースツリーのノードにルートノードからアクセスすることができます。また、相対ロケーションパスを使えば、現在位置からノードにアクセスすることができます。
このような起点の違いは別にして、ロケーションパスは、ロケーションステップ(location step)と呼ばれるたどり指定の単位をつなぎ合わせて表現されます。
| ロケーションパス=(/)ロケーションステップ/ロケーションステップ/... |
相対ロケーションパスは、XPath を利用する規格(XSLT など)において何らかの方法でXMLツリーのあるノードが指定された場合、そこからツリーをたどるときに指定する方法です。(今回の記事ではXPath 単体での説明なので、XPathの指定例としては絶対ロケーションパスを使用しています)
ロケーションステップは、軸(axis)、ノードテスト(node test)、述語(predicate)の3つ部分から構成されています。軸とノードテストの2つだけを使ったロケーションステップは次のように書きます。
| ロケーションパス=軸::ノードテスト |
軸は、起点からノードをたどる方向を決める指定です。XPath では、ロケーションパスで使用できる13の軸が用意されています。
|
軸 |
説明 |
| child | 子ノード |
| descendant | 子孫ノード(子ノード、子ノードの子ノード...) |
| parent | 親ノード |
| ancestor | 祖先ノード(親ノード、親ノードの親ノード...) |
| following-sibling | 起点ノードの兄弟ノードのうち起点ノードより文書順で後に来るノード |
| preceding-sibling | 起点ノードの兄弟ノードのうち起点ノードより文書順で前に来るノード |
| following | 文書順で起点ノードより後に位置するノードすべて(子孫ノードは含まれない) |
| preceding | 文書順で起点ノードより前に位置するノードすべて(祖先ノードは含まれない) |
| self | 起点ノード自身 |
| descendant-or-self | 起点ノードとその子孫ノード |
| ancestor-or-self | 起点ノードと祖先ノード |
| attribute | 起点ノードに従属する属性ノード |
| namespace | 起点ノードに従属する名前空間ノード |
attribute とnamespace 以外のノードを図示すると次のようになります。

図4:たどり方向を指定する11の軸(attribute とnamespase を除く)
軸で決まった方向の中でどのようなノードを選択するのかを指定するのがノードテストです。ノードテストには、特定の要素名やキーワードを書きます。そのようなキーワードを含め、"軸::"の先に書く情報と、その意味について次の表に示します。
|
ノードテスト |
説明 |
| 名前(要素名など) | attribute軸の場合、属性名。namespace軸の場合、名前空間の接頭辞。それ以外の場合、要素型名 |
| text() | テキストノードすべて |
| comment() | コメントノードすべて |
| processing-instruction() | 処理命令すべて |
| processing-instruction (処理命令ターゲット) |
指定された処理命令ターゲットを持つ処理命令すべて |
| node() | 任意の型のノードすべて |
| * | 軸によって決まっているノード型のノードすべて。大抵の場合、要素名。"名前空間接頭辞:*"と書くことによって、特定の名前空間に属するノードを選択することも可能。 |
このようなロケーションパスによって、あるノードを起点として、ツリー上を自由にたどることができるようになります。ここで注目したいのは、ノードはXMLの要素だけでなく、属性や他のすべてのタイプのノードにアクセス可能だということです。このようなXPath の機能がXSLTの変換能力を高めています。
たとえば、次のようなたどりによるノード指定を行う ことを考えましょう。
「ルートノードの子ノードの"catalog"要素のさらに子ノードの"CD"要素」
これは、XPath の絶対ロケーションパスとして次のように表現されます。
| /child::catalog/child::CD |
XPathでは、軸を表すキーワードに対してchild::が省略できることになっています。したがって、上記のロケーションパスは次のようにも指定できることになります。
| /catalog/CD |
これを次のXML データに適用するとどこの位置が選択されるでしょうか。
| <catalog> <CD type=" クラシック "> <title> コントラスツ </title> <price>1380</price> </CD> <CD type=" ジャズ "> <title>スピリチュアルトゥスイング</title> <price>3350</price> </CD> <CD type=" クラシック "> <title> 月の光 </title> <price>2000</price> </CD> </catalog> |
答えは、catalog要素の下の3つのCD要素です。このように、XPath指定は、ノードをたどりながら、一般に複数のノードを選択できます。
さて、上記のような複数のノードから特定のノードを絞り込むこともできます。それを行うには、ロケーションパスにおいて、ロケーションステップに述語(predicate)を加えます。述語を含むロケーションステップは次のように書きます。
| ロケーションパス=軸::ノードテスト[述語] |
述語としては、XPathの式(expression)を書きます。この式は、その前の「軸::ノードテスト」で選択されたノードの1つ1つを評価し、評価結果が「真」となるものだけを残します。そのような意味でノードの「絞り込み」を行うのです。
| /catalog/CD[type=" ジャズ "] |
たとえば、次のような XPath 指定があったとしましょう。
これを上記のXMLデータに適用するとどうなるでしょうか。[@type="ジャズ"] によって、「type 属性の値が"ジャズ"である」という式が評価された結果真となる要素を指す部分だけが残ります。
| <CD type=" ジャズ "> <title>スピリチュアルトゥスイング</title> <price>3350</price> </CD> |
この述語はロケーションパスの中の途中のロケーションステップとして書くことができますので、次のような指定も可能です。
| /catalog/CD[type=" ジャズ "]/title |
このようにすると、/catalog/CD[type= ≪ジャズ"] で選択された一つの要素ノードの下のtitle要素(<title> スピリチュアルトゥスイング </title>) が選択されることになります。