Rebol3 Code Examplex
JSON pointer
Navigate JSON documents using pointer syntax.
Rebol [
title: "Rosetta code: JSON pointer"
file: %JSON_pointer.r3
url: https://rosettacode.org/wiki/JSON_pointer
]
get-json-pointer: function[
data [map!] "Decoded JSON data"
ptr [string!] "JSON pointer"
][
if empty? ptr [return data]
if ptr == "/" [return select data ""]
if ptr/1 != #"/" [do to error! "Invalid JSON pointer!"]
parts: split next ptr #"/"
forall parts [
parse parts/1 [any [to #"~" [
change "~1" #"/" |
change "~0" #"~" | skip
]]]
any [
attempt [change parts to word! parts/1]
attempt [change parts 1 + to integer! parts/1]
]
]
insert parts 'data
get as path! parts
]
data: decode 'json {{
"wiki": {
"links": [
"https://rosettacode.org/wiki/Rosetta_Code",
"https://discord.com/channels/1011262808001880065"
]
},
"": "Rosetta",
" ": "Code",
"g/h": "chrestomathy",
"i~j": "site",
"abc": ["is", "a"],
"def": { "": "programming" }
}}
foreach ptr [
"" "/" "/ " "/abc" "/def/" "/g~1h" "/i~0j"
"/wiki/links/0" "/wiki/links/1" "/wiki/links/2"
"/wiki/name" "/no/such/thing" "bad/pointer"
][
printf [20 "--> "][
mold ptr
try/with [mold get-json-pointer data :ptr][ as-red "error!" ]
]
]Output:
"" --> #[
wiki: #[
links: ["https://rosettacode.org/wiki/Rosetta_Code" "https://discord.com/channels/1011262808001880065"]
]
"" "Rosetta"
" " "Code"
"g/h" "chrestomathy"
i~j: "site"
abc: ["is" "a"]
def: #[
"" "programming"
]
]
"/" --> "Rosetta"
"/ " --> "Code"
"/abc" --> ["is" "a"]
"/def/" --> "programming"
"/g~1h" --> "chrestomathy"
"/i~0j" --> "site"
"/wiki/links/0" --> "https://rosettacode.org/wiki/Rosetta_Code"
"/wiki/links/1" --> "https://discord.com/channels/1011262808001880065"
"/wiki/links/2" --> _
"/wiki/name" --> _
"/no/such/thing" --> error!
"bad/pointer" --> error!