始めに
XPathを使う場合、いまだに1.0で行われることが多い状況ですが、2017年には3.1が発表され、数多くの機能が追加されました。
XML Path Language (XPath) 3.1: 日本語訳
またXPath3.1に対応した実装としてJavaScriptで動作するSaxonJSがあります。
https://www.saxonica.com/saxon-js/index.xml
このようにXPath3.1は十分に身近な存在としてなるはずですが、実際に試そうとなると難しい面があるのは否めません。
そこで私が気軽に何度もXPathを試せる環境を用意しました。
https://inomoto-hironobu.github.io/app/xpath3/xhtml.xhtml
これで環境は整いましたが、では実際にどのように試していけばいいかの道しるべが、今はあまりない状況です。
そこで、本記事ではXPath3.1のクックブックとしてスムーズに学習を進める手伝いになるような書き方にしています。
以下の書き方でトピックを作っていきます。
- やりたいこと(何をするか)
- コード
- text(コンテキストに入れるオブジェクトのテキスト)
- xpath
- result(コンソールに表示される結果)
- 解説
今後ともトピックの追加をしていくつもりですが、一人では限界がありますので、お手伝いいただければと思います。
また以下のサイトが役に立ちます。
SaxonJSのドキュメント
Altovaのドキュメント
クックブック
文字列の長さを測る
やりたいこと
ある文字列の長さを測りたい。
コード
本日は晴天なり
string-length(.)
7
解説
XPath3.1では処理対象とする型はXMLにとどまりません。
文字列、JSONなどにも対象を広げ、より汎用的な処理言語となっています。
ここでは単純な文字列の長さを測っています。
ドット(.)はコンテキスト、つまり入力の文字列を表しています。
あとは関数を使って長さを計算しています。
入力なしにXPathを試す
やりたいこと
入力値を用意するのが面倒なので入力なしでもXPathを試したい。
コード
(1,3,5)[2]
3
解説
XPath3.1では式によって様々なオブジェクトを生成できます。
シーケンス、マップ、関数など多彩です。
例の式では数字3つを持つシーケンスを生成し、2番目の要素を取り出しています。
例えばちょっとしたビルトイン関数を試すだけならリテラルを生成する書き方で試す方が楽でしょう。
JSONの経路をたどりたい
やりたいこと
JSONのあるプロパティの値を経路をたどって得たい
コード
{
"hoge":{
"foo":"test",
"bar":"test2"
}
}
?hoge?bar
test2
解説
JSONのマップ構造の延長にある値を得ようとするときは、非常に簡潔に値を得ることが可能です。
ルートとなるコンテキストから?で名前を連ねていくだけです。
直接配列を処理する
やりたいこと
XPathに直接配列を渡し、特定の位置の要素を取り出したい。
[[1,3,5]]
.[1]=>array:get(1)
3
解説
XPathではシーケンスと配列という、似て非なる概念が混在しています。
シーケンスは多次元にできませんが、配列は多次元にできます。
一方、JSONからXPathへの転換は少し複雑です。
まずJSONの配列は、まずはシーケンスに変換されます。
しかしもし、配列の要素としての配列であれば配列に転換する、という仕様です。
さらにXPathの入力においては要素が1つを超えるシーケンスを渡すことができません。
例えばこのJSONを渡すとエラーになります。
[1,3,5]
Context item is a sequence of more than one item
そこで例では、配列に一つの配列が含まれるJSONを入力として渡し、1つの配列を持つシーケンスに転換されるようにして実質的に配列が渡されたかのような処理を行っているわけです。