🔑
[XPath 3.1]`$`付きのkeyを持つJSONを辿りたい
XPath 3.1では、JSON由来の構造array,mapについて値を得るとき、短縮記法があります。
JSONの例
{
"a": "value",
"b": {
"nested": "value2"
}
}
nested
の値value2
を得るには、上記のJSONがfn:parse-json()
でXDM構造になっていて変数$json
に格納されているとして、次のように辿れます。
(: value2が返る :)
$json?b?nested
ところでXPathでは、今しがた変数$json
と書いたように、$
記号を使って変数を示します。
次のようなJSONがあったとします。
{
"prop":{
"myColor": {
"$type":"color",
"$value":"red"
},
"width":{
"$type": "dimension",
"$value": "100px"
}
}
}
このJSONでkey名を辿ろうとすると$type
や$value
がkey名に登場します。これを先程の記述方法で書こうとしても(少なくともXSLTでは)エラーになってしまいます。
(: これはエラー :)
$json?prop?width?'$type'
この回避方法ですが、本記事の最初に述べたように、?key名
の記法は短縮記法です。これをややちゃんと書くと?(key名)
[1]となります。
(: 'dimension'が返る :)
$json?prop?width?('$type')
これで目的が達成できます。
ちなみに述部も使えるので、$type
の値がcolor
となるmapの$value
の値は次のようになります。
(: 'red' が返る :)
$json?prop?*[.?('$type') eq 'color']?('$value')
さて、?()
演算子は2 to 4
で2,3,4
を返したりと他にも色々使い方があります。函数が返す型の関係で仕方なくmapやarrayが出てくるときに?()
を使ってmapやarrayをはがした形で値を受けとったりできるExampleがXPath 3.1仕様の3.11.3に載っています。
XPath 4.0ではrecordとrecord用の演算が追加予定なので、目的によってはもう少しやりやすくなるかもしれません。
参考資料
-
この記法自体も短縮記法っぽくみえますが、arrayとmapを区別せず探索する記法としてはこうなる ↩︎
Discussion