XML Path Language (XPath(エックスパス)) は、マークアップ言語XML に準拠した文書の特定の部分を指定する言語構文である。XPath自体は簡潔な構文 (式言語) であり、XMLベースのマークアップ言語ではない。標準化団体W3C (World Wide Web Consortium) で開発され、1999年11月16日に XML Path Language (XPath) 1.0 がXSL Transformations (XSLT) 1.0 と同時に勧告として公表された[1][2]。XPathは、XSLT と XSL-FO とともにXSL の構成要素である。2007年1月23日、W3C で XPath 1.0 の次期バージョンが制定され、XPath 2.0 が XSLT 2.0 と同時に勧告された。2014年4月8日に XPath 3.0、2017年3月21日に XPath 3.1 が勧告された。他に、XPathを拡張したようなものとしてXQuery がある。
XPathは、XML文書中から必要な要素群(サブセット)を取り出す、などといった用途に使うものとして、急速に受け入れられていった。なお、もともとはXPathは、XSL (XSLT) とXPointer に共通する構文と振る舞いのモデルを目標としていた。
XSLTでは、XML文書内の処理対象などの指定に、XPathを使用する。一般に、XSLT処理系を実装するには、XPath処理系のライブラリなどを利用してXPathを取り扱う必要がある。
日本では日本工業規格(JIS)に、JIS X 4160 として XPath 1.0 の翻訳版がある。
XPathのデータモデルでは、XML文書はルートノードを頂点とするノードの木構造であり、以下の7種類のノードから構成される (参考:XML) 。
XPathで最も一般的な式は、ロケーションパスである。ロケーションパスにより、XML文書のあるノード(現在のコンテクストノード)を基準として、別のノードもしくは複数のノード(ノード集合)が指定される(指定されるノードが0個すなわち1個も存在しない場合もある)。
ロケーションパスは、1つまたは複数のロケーションステップの並びとして記述される。複数のロケーションステップでロケーションパスが記述される場合、各ロケーションステップは/
により区切られる。
ロケーションパスを構成する各ロケーションステップは、次の3つの要素から構成される。
ロケーションステップは次の2種類の構文を使って記述することができる。
省略構文は簡潔な構文であり、よく使われる多くの既定値を使い省略してロケーションステップを記述することができる。
省略構文による簡単なロケーションパスの記述例を示す。
/A/B/C
この例では、先頭が/
となっている絶対パスであり、0個以上のC
要素を選択する。選択されたC
要素はB
要素の子要素(child element)であり、そのB
要素はA
要素の子要素であり、A
要素はそのXML文書のルート要素である。
XPathの構文は、URI(Uniform Resource Identifier)の構文やファイルパスの構文に似せて、設計されている。
省略構文では、先の例より複雑な式を記述することもできる。ただし完全な構文と比べると記述能力は制限される。
child
軸以外にもいくつかの軸(attribute
軸、descendant-or-self
軸、self
軸、parent
軸)を指定することができる。[
と]
を後ろにつけて述語を指定することができる。少し複雑なロケーションパスの例を示す。
A//B/*[1]
この例は、先頭が/
となっていない相対パスであり、任意の名前の(*
)最初の要素([1]
)を選択する。選択された「最初の要素」はB
要素の子要素(/
)であり、そのB
要素はA
要素の直接的または間接的な子要素(子孫要素、//
)であり、そのA
要素は現在のコンテクストノードの子要素である。
省略構文の一覧と正式な定義については後の#完全な構文と省略構文の対応関係の節で示す。
完全な構文の一般式は以下の形となる。
/軸方向::名前空間:ノードテスト[述語]/~~
先の#省略構文の節で示した2つの例を、省略しない完全な構文によって書き直すと次のようになる。
/child::A/child::B/child::C
child::A/descendant-or-self::node()/child::B/child::*[1]
このように完全な構文で記述されたロケーションパスの各ロケーションステップにおいては、
child
やdescendant-or-self
のように明示的に指定する。::
を記述し、さらにノードテストをA
やnode()
、*
のように記述する。[
と]
を後ろにつけて述語を指定することができる。ロケーションステップの軸の記述は、XML文書の木構造において、方向を指定する。XPath仕様で定義されている13種類の軸(#完全な構文)を示す。
child
descendant
parent
ancestor
following-sibling
preceding-sibling
following
preceding
attribute
namespace
self
descendant-or-self
ancestor-or-self
省略構文でattribute
軸を使う例を示す。
//a/@href
この例では、href
属性ノードの集合を選択する。選択されたhref
属性ノードは、XML文書内のいずれかのa
要素ノードに属している。
self
軸は、後述する述語の中でその述語の直前のノードテストで選択されたノードを記述するためによく使われる。例を示す。
h3[.='関連項目']
この例では、カレントノードの子ノードであり、かつ内容のテキスト'関連項目'
をもつh3
要素が選択される。
ロケーションステップのノードテストは、式もしくは特定のノード名によって記述される。例えば、名前空間接頭辞gs
が定義されているXML文書で、//gs:enquiry
とノードテストが記述された場合、gs
名前空間下のenquiry
をノード名とする全てのノードの集合が、このノードテストの指定の対象となる。
ノードテストの書式を示す[3]。
attribute
軸とnamespace
軸以外の軸の場合は、その名前をもつ全ての要素ノードを指定する。attribute軸
の場合はその名前の全ての属性ノードを指定し、namespace軸
の場合は名前空間ノードを指定する。text()
<k>こんにちは</k>
の中の'こんにちは'
comment()
<!-- コメント -->
processing-instruction()
<?xsl-stylesheet href="article.css" ?>
processing-instruction(処理命令ターゲット)
という書式での記述も可能であり、この例の場合はprocessing-instruction('xsl-stylesheet')
と記述すると指定対象となる。node()
*
attribute
軸とnamespace
軸以外の軸の場合は要素ノードを意味し、attribute
軸の場合は属性ノードを、namespace
軸の場合は名前空間ノードを、それぞれ意味する。ロケーションステップの完全な構文と省略構文の対応関係を次に示す[1][4]。
完全な構文 | 省略構文 | 説明 |
---|---|---|
child:: | (省略して何も書かない) | コンテクストノードの子ノード |
attribute:: | @ | コンテクストノードが要素の場合、その属性ノード |
/descendant-or-self::node()/ | // | コンテクストノード自身とコンテクストノードの子孫ノード |
self::node() | . | コンテクストノード自身 |
parent::node() | .. | コンテクストノードの親ノード |
ロケーションステップでは、ノードテストの後に、角括弧でくくる述語で複雑な式を記述して、ノードテストで指定されたノード集合を絞り込むことができる。ノード集合を絞り込む必要が無い場合は、述語は記述しない。
簡単な例を示す。
//a[@href='help.php']
この例では、[@href='help.php']
の部分が述語である。このXPath式は、href
属性をもち、かつその属性値が'help.php'
である、全てのa
要素ノードを指定する。
先の例では述語の数は1つであったが、ロケーションパスを構成するロケーションステップごとに、複数の述語を指定することができる。すなわち、絞り込み条件を複数重ねて指定することができる。指定できる述語の数に制限は無い。
述語は、その述語を含むロケーションステップのコンテクストを変更することは無い。その直前のノードテストで指定されたノード集合がそのロケーションステップのコンテクストであり、述語が指定されることでコンテクストが変更されることは無い。
複雑な例を示す。
//a[@href='help.php'][name(..)='div'][../@class='header']/@target
この例は、a
要素のtarget
属性の値を指定する。ただし、このXPath式の最初のロケーションステップには3つの述語が記述されており、a
要素のうち
a
要素のhref
属性の値が'help.php'
であり、a
要素の親要素の要素名がdiv
であり、div
)のclass
属性の値が'header'
である、a
要素のみが、最初のロケーションステップの指定対象となる。最終的には、最初のロケーションステップで絞り込まれて指定対象となったa
要素のtarget
属性が指定されることになる。
XPath 1.0 で規定されているデータ型と演算子、関数を説明する。
データ型は次の4種類が定義されている。
演算子 | 備考 |
---|---|
/ | 先述。 |
// | 先述。 |
| | 2つのノード集合の和集合のノード集合を返す。 |
and | 論理積 |
or | 論理和 |
+ | 足し算 |
- | 引き算 |
* | 掛け算 |
div | IEEE 754に基づく割り算 |
mod | 剰余 |
= | 等価 |
!= | 等価でない |
< | 小なり |
<= | 小なりまたは等価 |
>= | 大なりまたは等価 |
> | 大なり |
関数名 | 備考 |
---|---|
concat | 与えられた文字列を連結した文字列を返す。 |
substring | 指定された範囲の部分文字列を返す。 |
contains | 指定された文字列が部分文字列として含まれる場合に真値を返し、それ以外の場合に偽値を返す。 |
starts-with | 指定された文字列が先頭の部分文字列である場合に真値を返し、それ以外の場合に偽値を返す。 |
ends-with | 指定された文字列が末尾の部分文字列である場合に真値を返し、それ以外の場合に偽値を返す。 |
substring-before | 指定された文字列よりも前にある部分文字列を返す。 |
substring-after | 指定された文字列よりも後ろにある部分文字列を返す。 |
translate | |
normalize-space | |
string-length | 文字列の長さを返す。 |
関数名 | 備考 |
---|---|
sum | 総和を返す |
round | 四捨五入関数 |
floor | 床関数 |
ceiling | 天井関数 |
関数名 | 備考 |
---|---|
name | 名前空間付きの要素名を返す。 |
local-name | 名前空間なしの要素名を返す。 |
namespace-uri | 名前空間のURIを返す。 |
position | |
last |
関数名 | 備考 |
---|---|
string | |
number | |
boolean |
比較的よく使われる関数については、次の節以降で少し詳しく述べる。完全な定義は、W3Cの勧告(日本語訳)を参照。
XPathの式は、丸括弧の(
と)
で括りグループ化して評価順序を明記することができる。
述語には演算子を使った式を含めることができる。論理式 (論理値を返す式) は、and
演算子やor
演算子でつなげることや、not
関数の引数にすることができる。文字列 (string) にはUnicodeの文字を含めることができる。述語で演算子を使う例を示す。
//item[@price >= 2*@discount]
この例では、price
属性の数値がdiscount
属性の数値の2倍以上であるitem
要素の集合を選択する。
演算子|
は、述語の内部でも、述語の外部でも、ノード集合の和を求めるために使うことができる。述語の外部で|
演算子を使う例を示す。
v[x or y] | w[z]
この例では、一つのノード集合を返す。返されるノード集合は、処理中のコンテクストにおいて、子要素としてx
要素もしくはy
要素をもつv
要素の集合と、子要素としてz
要素をもつw
要素の集合の、和集合である。
position()
count(
node-set)
id(
object)
name(
node-set?)
string(
object?)
string-length(
string?)
substring(
string,
number,
number?)
concat(
string,
string,
string*)
contains(
string1,
string2)
string1
に文字列string2
が含まれていた場合にはtrue
関数が返すのと同じ値を返す。含まれていなかった場合はfalse
関数が返すのと同じ値を返す。normalize-space(
string?)
not(
boolean)
sum(
node-set)
次のXML文書でXPathを例示して説明する。
<?xml version="1.0" encoding="utf-8"?><document><!-- XML文書 --><chaptertitle="第1章"><paragraph>段落</paragraph><paragraph>次の段落</paragraph><paragraph>さらに次の段落</paragraph><paragraph>最後の段落</paragraph></chapter><chaptertitle="第2章"><paragraph>段落</paragraph></chapter></document>
/document
: ルート要素document
を選択する。/*
: 名前を限定せずにルート要素を選択する。この場合は同じくdocument
が選択される(XML文書は必ず一つのルート要素をもつ)/document/chapter
:document
要素の子要素である全てのchapter
要素を選択する。/document/chapter[1]
:document
要素の子要素のうち1番目のchapter
要素を選択する。//paragraph
: 文書内の全てのparagraph
要素を選択する。//chapter[@title="第1章"]/paragraph
:title
属性の値が "第1章" であるchapter
要素の子要素である全てのparagraph
要素を選択する。XPath 2.0 は2007年1月23日に標準化団体W3C で勧告された。XQuery 1.0 は XPath 2.0 の拡張である。また XPath 2.0 はXSLT 2.0 でも採用されている。
XPath 2.0 仕様は、1.0 と比べて大規模になっており非常に多くの機能が規定されている。そのうち特に重要な変更は、多様なデータ型を扱えるようになったことである。XPath 2.0 では、スキーマ言語XML Schema で規定されている組み込みのアトミックデータ型と、スキーマで定義されたユーザ定義型を、扱うことができる。あらゆる値は、シーケンスとして扱われる。一つの文字列値やノードは、シーケンスに含まれる要素の一つと位置づけられる。XPath 1.0 のノード集合は、XPath 2.0 では何らかの順序をもつシーケンスに、置き換わる。多様な型を扱うために、XPath 2.0 では関数と演算子が大幅に拡張される。
XPath 2.0 は XQuery 1.0 のサブセットとなっている。XPath 2.0 は XQuery 1.0 の構文のパス式を構成する。XQuery 1.0 の FLWOR と呼ばれる式においては、for
句の構成要素となる。
![]() | この節の加筆が望まれています。 |
2014年4月8日に XPath 3.0 が勧告された。XQuery 3.0 は XPath 3.0 の拡張である。
javax.xml.xpath
[5] パッケージがあり、XPath 1.0 が実装されている。XPathFactory.newInstance().newXPath()
にて、XPath のインスタンスを作ることができ、XPath.evaluate()
にて XPath を評価できる。
HTML ではなく、一般の XML に関しては、XMLHttpRequest を使うと DOM木を作ることができ、どちらに対しても XPath が使える。Internet Explorer の場合は、XMLDomNode.selectNodes()
[6] にて XPath が使える。Internet Explorer 以外のブラウザでは、DOM Level 3 XPath の仕様通り、XPathEvaluator.evaluate()
[7] にて、XPath が扱える。
現在では、ブラウザ標準で XPath が使えるが、2007年くらいまでは、JavaScript で実装した XPath が作られていて、 JavaScript-XPath[8]やGoogle AJAXSLT[9]などが XPath を実装している。
XSLTでもノードの指定に XPath を用いる。XSLT処理系には以下のようなものがある。
xml-stylesheet
処理命令が中に書かれたXML文書を表示する場合、そのXML文書を指定されたXSLプログラムで処理して得られるXML文書を画面に表示する。 ウィキメディア・コモンズには、XML Path Languageに関するメディアがあります。