XPathについての概略
この記事の概要
- 本記事はXML言語の一つ「XPath1.0」の仕様に関する概略である。主に軸方向(Axis)と関数の定義をXPath仕様書の邦訳から要約、加筆した。
- 本記事はXML及びXPathについて一定の理解のある者を対象としており、初めてXPathを学習する方は別の解説記事を参照されたい。
XPathの概要
XPath は、XML ドキュメントの一部をアドレッシングするための言語であり、XSLT および XPointer で使用するように設計されている。
XPathは、マーク付け言語において要素を特定する手段の一つである。アドレス形式で記述し、基本的な記法は軸方向::名前空間:ノードテスト[述語]/~~
となる。これをロケーションパスと言い、"/
"で区切られた一つの記述をロケーションステップと呼ぶ。
ロケーションパスは、"/
"で始まるものを絶対パス、始まらないものを相対パスとして展開する。絶対パスではルートノード(後述)がコンテキストノードとなり、相対パスでは基準ノードがコンテキストノードになる。ルートノードとルート要素は異なる点に注意。
ノード(Node)
XPathでは、マーク付け文書をノードという単位に分解し、木構造を展開する。ノードには「ルートノード」「要素ノード」「属性ノード」「テキストノード」「プロセッシングインストラクションノード」「コメントノード」「ネームスペースノード」の7種類がある。
- ルートノード
- 全てのノードを包括するノード。通常、ルートノードは1個の要素ノードを子に持つ。
- 要素ノード
- マーク付け文書の要素に当たるノード。属性ノードとテキストノードは、必ず要素ノードを親に持つ。
- 属性ノード
- 要素ノードが示す要素の内容のうち、属性に当たるノード。
- テキストノード
- 要素ノードが示す要素の内容のうち、他のノードに属さない平文に当たるノード。
- プロセッシングインストラクションノード
- 処理命令文に当たるノード。script要素の中身ではない(こちらはscript要素ノードの子のテキストノードである)
- コメントノード
- コメント文に当たるノード。
- ネームスペースノード
- 名前空間に当たるノード。
軸方向(Axis)
軸方向とはコンテキストノードから対象となるノードへの樹関係を示すものである。頻繁に用いられる軸方向には略記法が定義されている。
- ancestor-or-self::
- コンテキストノード自身とその先祖。
- ancestor::
- コンテキストノードの先祖。
- parent::
- コンテキストノードの親。"
parent::node()
"は"..
"と省略出来る。
- preceding::
- コンテキストノードより先に記述されたノード(兄や伯父を含む)但し先祖、属性、名前空間ノードは除く。
- preceding-sibling::
- コンテキストノードの兄(自身より先にある兄弟ノード)但しコンテキストノードが属性又は名前空間ノードの場合は空。
- self::
- コンテキストノード自身。"
self::node()
"は".
"と省略出来る。
- following-sibling::
- コンテキストノードの弟(自身より後にある兄弟ノード)但しコンテキストノードが属性又は名前空間ノードの場合は空。
- following::
- コンテキストノードより後に記述されたノード(弟や叔父を含む)但し子孫、属性、名前空間ノードは除く。
- child::
- コンテキストノードの子供。ロケーションステップでは軸方向を省略すると"
child
"が自動的に補完される。
- descendant::
- コンテキストノードの子孫。
- descendant-or-self::
- コンテキストノード自身とその子孫。"
/descendant-or-self::node()/
"は"//
"と省略出来る。
- attribute::
- コンテキストノードの属性ノード。コンテキストノードが要素ノードでなければ空。"
attribute::
"は"@
"と省略出来る。
- namespace::
- コンテキストノードの名前空間ノード。コンテキストノードが要素ノードでなければ空。
ノードテスト
ノードテストとは軸方向から該当するノードを指定するものである。接頭語を用いて名前空間を指定することも出来る。
注意しなければならないのは名前空間の指定を省略した場合、xmlnsで指定されたデフォルト名前空間は適応されずnull(名前空間が存在しない)扱いになる点である。ノード名の他、以下の記法が存在する。
- node()
- 全てのノード。
- *
- 全ての主ノード(
attribute::
であれば属性、namespace::
であれば名前空間、それ以外では要素ノード)
- text()
- テキストノード
- comment()
- コメントノード
述語
述語とは、ノードテストで選出されたノード集合を、さらに振り分けする条件を記述する部分である。評価には式を用い、式の値が真のノードのみが選出される。
式と演算子
式とは述語中に記述されるノードの条件を規定するものである。
- ロケーションステップ
- ロケーションステップは式としても使える。例えば、
para[child::bora]
はbora要素を子供にもつpara要素に対して真となる。
- ブール値
- 演算子を用いて条件を指定することも出来る。文字列の場合はシングルクォートもしくはダブルクォートで括る必要がある。
- 例えば
para[child::bora/child::text() = "いろは"]
は「いろは」というテキストノードをもつbora要素を子供にもつpara要素に対して真となる。
- 演算子には、論理和を表す「or」、論理積を表す「and」、等価を表す「=」、不等価を表す「!=」、超過を表す「>」、以上を表す「>=」、以下を表す「<=」、未満を表す「<」などがある。但し<を使う場合は
<
を使うなどをしてエスケープしなければならない。
- 数値演算子
- 数値演算子はノードを数値として(数値に変換して)評価する。数値はそのまま、それ以外の場合はnumber()関数を通した時と同じように数値に変換されて演算される。
- 数値演算子として、加算を表す「+」、減算を表す「-」、除算を表す「div」、除算後の余りを表す「mod」などがある。乗算を表す演算子は存在しない。
コア関数ライブラリ
関数とは、ノードテストや述語中に記述することでその引数をロケーションステップや式の評価に用いるものである。
ノード集合関数
- last()
- 評価中のコンテキストのサイズを返す。
- position()
- 評価中のコンテキストの位置を返す。なお、述語中に整数のみを記述した場合この関数が代入されたのと同じ振る舞いをする。
- count(○○)
- ○○で指定したノード集合に含まれるノードの数を返す。
- id(○○)
- ○○というユニークIDを持つ要素を返す。
- local-name(○○?)
- ○○で指定したノード集合のうち一番最初に記述されたノードのノード名(ローカルパート)を返す。ノード名を持たない場合は空。また○○を省略した場合はコンテキストノードで評価する。
- namespace-uri(○○?)
- ○○で指定したノード集合のうち一番最初に記述されたノードの名前空間URIを返す。ノード名又は名前空間を持たない場合は空。また○○を省略した場合はコンテキストノードで評価する。
- name(○○?)
- ○○で指定したノード集合のうち一番最初に記述されたノードのノード名と名前空間URIを返す。ノード名を持たない場合は空また○○を省略した場合はコンテキストノードで評価する。
文字列関数
- string(○○)
- ○○で指定されたオブジェクトを文字列に変換して返す。変換規則は以下の通り。
-
- ノード集合の場合、一番最初に記述されたノードの文字列(nullの場合はnull)を返す。
- 数値の場合、正の無限大は「Infinity」、負の無限大「-Infinity」、「NaN」やそれ以外の数値はそれぞれ記法のまま文字列にして返す。但し001のような前ゼロは全て省かれる。
- ブール値の場合、真であれば「true」、偽であれば「false」を返す。
- concat(○○,○○,○○*)
- ○○で指定された文字列を連結して返す。
- starts-with(○○,××)
- ○○で指定された文字列が××で指定された文字列で始まっていれば真、それ以外であれば偽を返す。
- contains(○○,××)
- ○○で指定した文字列が××で指定した文字列を含んでいれば真、それ以外であれば偽を返す。
- substring-before(○○,××)
- ○○で指定した文字列のうち××で指定した文字列よりも前にある文字列を返す。××が見つからなければ空。例えば
substring-before('1999/04/01','/')
は「1999」を返す。
- substring-after(○○,××)
- ○○で指定した文字列のうち××で指定した文字列よりも後にある文字列を返す。××が見つからなければ空。例えば
substring-after('1999/04/01','/')
は「04/01」を返す。
- substring(○○,××,△△?)
- ○○で指定した文字列のうち××で指定した位置の文字列から△△で指定した数値分の長さの文字列返す。××が見つからなければ空。△△を省略した場合は××以降から最後までの文字列を返す。例えば
substring('12345',2,3)
は「234」を返す。最初の文字は1から始まる点に注意。
- string-length(○○?)
- ○○で指定された文字列の文字数を返す。○○を省略した場合はコンテキストノードの文字列で評価する。
- normalize-space(○○?)
- ○○で指定された文字列を正規化(前後の空白を除去し、連続する空白を一つの空白に置き換え)する。○○を省略した場合はコンテキストノードの文字列で評価する。
- translate(○○,××,△△)
- ○○で指定された文字列内に××で指定された文字列内の文字があれば△△で指定された文字列内と同じ位置の文字を置き換えて返す。例えば
translate('bar','abc','ABC')
は「BAr」を返す。もし△△が省略、もしくは××に対応する長さが無い場合は対応する文字を削除して返す。例えばtranslate('--aaa--','abc-','ABC')は「AAA」を返す。
ブール値関数
- boolean(○○)
- ○○で指定されたオブジェクトをブール値(真偽値)にして返す。変換規則は以下の通り。
-
- ノード集合の場合、nullでない限り真を返す。
- 数値の場合、0ないしNaNでない限り真を返す。
- 文字列の場合、長さが0でない限り真を返す。
- not(○○)
- ○○で指定されたブール値が真ならば偽を、偽ならば真を返す。
- true()
- 常に真を返す。
- false()
- 常に偽を返す。
- lang(○○)
- コンテキストノードのxml:lang属性の属性値と○○で指定された文字列が大文字小文字を無視して等しければ真を返す。コンテキストノードがxml:lang属性を持たない場合は最も近い先祖のもつxml:lang属性値で評価され、もし先祖もxml:lang属性を持たない場合や属性値が異なる場合は偽を返す。
数値関数
- number(○○?)
- ○○で指定されたオブジェクトを数値に変換して返す。変換規則は以下の通り。
-
- 数字の場合はそのまま数値に、それ以外の文字列はNaNを返す(前後の空白は除去される)
- ブール値の場合、真であれば1、偽であれば0を返す。
- ノード集合の場合、まずはstring 関数と同様の規則で文字列に変換し、次にそれを文字列と同じ規則で数値に変換する。
- sum(○○)
- ○○で指定したノード集合内の各ノードの文字列を数値に変換し、それの合計値を返す。
- floor(○○)
- ○○で指定した数値よりも大きくない範囲で最も大きい整数を返す。つまり、小数を切り捨てて(負の場合は切り下げて)返す。
- ceiling(○○)
- ○○で指定した数値よりも小さくない範囲で最も小さい整数を返す。つまり小数を切り上げて(負の場合は切り捨てて)返す。
- round(○○)
- ○○で指定した数値に最も近い整数を返す。但し○○がNaN、無限大、Oの場合はそのまま。つまり、小数1位で四捨五入して返す。