🔑

[XPath 3.1]`$`付きのkeyを持つJSONを辿りたい

2024/11/01に公開

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 42,3,4を返したりと他にも色々使い方があります。函数が返す型の関係で仕方なくmapやarrayが出てくるときに?()を使ってmapやarrayをはがした形で値を受けとったりできるExampleがXPath 3.1仕様の3.11.3に載っています。
XPath 4.0ではrecordとrecord用の演算が追加予定なので、目的によってはもう少しやりやすくなるかもしれません。

参考資料

脚注
  1. この記法自体も短縮記法っぽくみえますが、arrayとmapを区別せず探索する記法としてはこうなる ↩︎

Discussion