XSLTはXML文書を別の形に変換する機能が充実しています。そして、その機能を実現するためには、変換元のXML文書のどの要素からデータを取り出すかなど、きめ細かく指定できることが必須となります。
この指定方法として、XPath(XML Path Language)と呼ばれる規則を使用します。XPathはXML文書の一部分を自由に指定する役割を持ち、XML文書に対して様々な操作を可能にします。
実はXPathは既出のサンプルでもう使用しています。その際は深く触れませんでしたが、今回はより詳しくXPathの仕組みについて見ていきます。
XPathとは
XPathは、XML文章をツリーとしてモデル化し、ルートノードを基点として、各ノード(要素や属性)への位置を指定できるようにします。
例えば以下のようなXML文書で考えて見ます。
<?xml version="1.0" encoding="UTF-8" ?> <books> <book id="0001"> <title>吾輩は猫である</title> <author>夏目 漱石</author> <price>648</price> </book> <book id="0002"> <title>風立ちぬ・美しい村</title> <author>堀 辰雄</author> <price>540</price> </book> </books>
このXML文書をモデル化したら下図のようになります。
ここで言う「ノード」とは上図の図形ひとつひとつのことを示し、それぞれが要素や属性をあらわします。その他にも、ノードには以下のような種類があります。
種類 | 内容 |
---|---|
ルートノード | ツリーの一番上にある「/」を示す。 |
要素ノード | 要素を示す。 |
属性ノード | 属性を示す。 |
テキストノード | 要素や属性の内容を示す。 |
コメントノード | コメントを示す。 |
処理命令ノード | 処理命令を示す。 |
名前空間ノード | 名前空間を示す。 |
絶対位置指定
XML文書全体を示すルートノードは「/」であらわします。そのルートノードの子孫を指定するには、先頭に/をつけて、その子ノードを/で区切っていきます。例えば、「book」要素を指定する場合は、「/books/book」と記述します。また、属性を指定する場合は名前の前に@(アットマーク)をつけます。例えば、「book」要素の「id」属性を指定する場合は、「/books/book/@id」と記述します。
このように、ルートノードからあるノードを指定する方法を絶対位置指定と言います。
相対位置指定
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="html" encoding="UTF-8" />
<xsl:template match="/">
<html>
<head>
<title><xsl:text>おすすめ小説</xsl:text></title>
<link rel="stylesheet" type="text/css" href="sample11.css"/>
</head>
<h1 class="sample">おすすめ小説</h1>
<table class="sample">
<tr>
<th>書籍</th>
<th><xsl:text>著者</xsl:text></th>
<th><xsl:text>価格</xsl:text></th>
</tr>
<xsl:apply-templates select="/books/book" />
</table>
</html>
</xsl:template>
<xsl:template match="/books/book">
<tr>
<td><xsl:value-of select="title" /></td>
<td><xsl:value-of select="author" /></td>
<td><xsl:value-of select="price" /></td>
</tr>
</xsl:template>
</xsl:stylesheet>
<xsl:apply-templates>により呼び出しているテンプレート内では「book」要素が変換対象となります。その呼び出されたテンプレート内では、現在処理中のノードが「book」要素となり、「book」要素を基点にして、他のノードを指定することができます。
「現在処理中のノード」のことをカレントノードと言います。上記したテンプレート内では「book」要素がカレントノードとなります。
ポイントは、<xsl:apply-templates>で別のテンプレートを呼び出した場合、呼び出された<xsl:template>要素は配下ではカレントノードは現在のテンプレートが処理を行っている対象の要素に移るという点です。
カレントノードは「.」(ピリオド)で指定することができます。また、要素名だけを記述すると、その要素名を持つカレントノードの子要素を指定したことになります。例えば、「book」要素がカレントノードの場合、「book」要素は「.」で指定します。またその配下の「title」要素を指定する場合は「./title」もしくは「title」と記述します。
このように、カレントノードから相対的に指定する方法を相対位置指定と言います。
XPathで使用する記号
XPathで使用する主要な記号とその内容は下表になります。
記号 | 内容 | サンプル |
---|---|---|
/ | 直下の要素 | book/price <book>要素直下の<price>要素を指定 |
// | 全ての子孫 | books//name <books>要素配下の全ての<name>要素を指定 |
. | 現在の要素 | ./book 現在のノード直下にある<book>要素を指定 |
* | 全ての子要素 | book/* <book>要素直下の全要素 |
@ | 属性名の接頭辞 | book/@id <book>要素のid属性 |
: | 名前空間セパレート | <name xml:lang=”ja”> |
他にもあるXPathの利用方法
Linuxなどに触れている方は、ファイルやディレクトリを指定する方法と同じ考え方であるとすぐに気がつくと思います。XML文書もファイルやディレクトと同じように、階層構造をたどって、特定の部分を指定するのです。
ただ、XPathは、前述した役割の他にも、XML文書にリンクを埋め込むXPointerやXML文書にデータを問い合わせるXQueryでも利用されるなど、まだまだ学ばなければならないことはありますが、現段階では各ノード(要素や属性)への位置を指定するものとおさえておけば良いでしょう。