JSON pointer: Difference between revisions
Content added Content deleted
Line 456: | Line 456: | ||
error: "bad/pointer" pointers must start with a slash or be the empty string |
error: "bad/pointer" pointers must start with a slash or be the empty string |
||
</pre> |
|||
=={{header|Phix}}== |
|||
Note that parse_json() in version 1.0.3 and earlier does not support unquoted keys or trailing commas, fixed in 1.0.4 but for now at least the dtxt constant below has a few additional quotes added and trailing commas removed. |
|||
<!--<syntaxhighlight lang="phix">(phixonline)--> |
|||
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span> |
|||
<span style="color: #008080;">include</span> <span style="color: #000000;">builtins</span><span style="color: #0000FF;">\</span><span style="color: #000000;">json</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span> |
|||
<span style="color: #008080;">function</span> <span style="color: #000000;">parseJSONPointer</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">p</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">p</span><span style="color: #0000FF;">=</span><span style="color: #008000;">""</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #0000FF;">{}</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">p</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]!=</span><span style="color: #008000;">'/'</span> <span style="color: #008080;">then</span> <span style="color: #7060A8;">throw</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"pointers must start with a slash or be the empty string"</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
<span style="color: #008080;">return</span> <span style="color: #7060A8;">apply</span><span style="color: #0000FF;">(</span><span style="color: #004600;">true</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">substitute_all</span><span style="color: #0000FF;">,{</span><span style="color: #7060A8;">split</span><span style="color: #0000FF;">(</span><span style="color: #000000;">p</span><span style="color: #0000FF;">,</span><span style="color: #008000;">'/'</span><span style="color: #0000FF;">,</span><span style="color: #004600;">false</span><span style="color: #0000FF;">),{{</span><span style="color: #008000;">"~1"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"~0"</span><span style="color: #0000FF;">}},{{</span><span style="color: #008000;">"/"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"~"</span><span style="color: #0000FF;">}}})[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">..$]</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span> |
|||
<span style="color: #008080;">function</span> <span style="color: #000000;">resolve</span><span style="color: #0000FF;">(</span><span style="color: #004080;">object</span> <span style="color: #000000;">json</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">sequence</span> <span style="color: #000000;">tokens</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">t</span> <span style="color: #008080;">in</span> <span style="color: #000000;">tokens</span> <span style="color: #008080;">do</span> |
|||
<span style="color: #004080;">integer</span> <span style="color: #000000;">jtype</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">iff</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span><span style="color: #0000FF;">(</span><span style="color: #000000;">json</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">and</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">json</span><span style="color: #0000FF;">)?</span><span style="color: #000000;">json</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]:</span><span style="color: #000000;">0</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">jtype</span><span style="color: #0000FF;">=</span><span style="color: #000000;">JSON_ARRAY</span> <span style="color: #008080;">then</span> |
|||
<span style="color: #000080;font-style:italic;">-- Note: we expect "JSON Pointers" to contain 0-based indices, |
|||
-- but Phix indices are 1-based, //and// parse_json() returns |
|||
-- sequences with first element of JSON_ARRAY/OBJECT/KEYWORD.</span> |
|||
<span style="color: #004080;">integer</span> <span style="color: #000000;">k</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">to_integer</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t</span><span style="color: #0000FF;">,-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">1</span> |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">k</span><span style="color: #0000FF;"><</span><span style="color: #000000;">1</span> <span style="color: #008080;">or</span> <span style="color: #000000;">k</span><span style="color: #0000FF;">>=</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">json</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span> <span style="color: #7060A8;">throw</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"bad index: "</span><span style="color: #0000FF;">&</span><span style="color: #000000;">t</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
<span style="color: #000000;">json</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">json</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> |
|||
<span style="color: #008080;">elsif</span> <span style="color: #000000;">jtype</span><span style="color: #0000FF;">=</span><span style="color: #000000;">JSON_OBJECT</span> <span style="color: #008080;">then</span> |
|||
<span style="color: #008080;">try</span> |
|||
<span style="color: #000000;">json</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">extract_json_field</span><span style="color: #0000FF;">(</span><span style="color: #000000;">json</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">t</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{})</span> |
|||
<span style="color: #008080;">catch</span> <span style="color: #000000;">e</span> |
|||
<span style="color: #7060A8;">throw</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t</span> <span style="color: #0000FF;">&</span> <span style="color: #008000;">" does not exist"</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">try</span> |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">json</span><span style="color: #0000FF;">={}</span> <span style="color: #008080;">then</span> <span style="color: #7060A8;">throw</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t</span><span style="color: #0000FF;">&</span><span style="color: #008000;">": no such field"</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
<span style="color: #008080;">else</span> <span style="color: #000080;font-style:italic;">-- native/keyword</span> |
|||
<span style="color: #7060A8;">throw</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"non subscriptable: %v [%s]"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">json</span><span style="color: #0000FF;">,</span><span style="color: #000000;">t</span><span style="color: #0000FF;">})</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
<span style="color: #008080;">return</span> <span style="color: #000000;">json</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span> |
|||
<span style="color: #008080;">constant</span> <span style="color: #000000;">dtxt</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">""" |
|||
{ |
|||
"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" }, |
|||
}"""</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">doc</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">parse_json</span><span style="color: #0000FF;">(</span><span style="color: #000000;">dtxt</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #008080;">constant</span> <span style="color: #000000;">tests</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span> |
|||
<span style="color: #008000;">""</span><span style="color: #0000FF;">,</span> |
|||
<span style="color: #008000;">"/"</span><span style="color: #0000FF;">,</span> |
|||
<span style="color: #008000;">"/ "</span><span style="color: #0000FF;">,</span> |
|||
<span style="color: #008000;">"/abc"</span><span style="color: #0000FF;">,</span> |
|||
<span style="color: #008000;">"/def/"</span><span style="color: #0000FF;">,</span> |
|||
<span style="color: #008000;">"/g~1h"</span><span style="color: #0000FF;">,</span> |
|||
<span style="color: #008000;">"/i~0j"</span><span style="color: #0000FF;">,</span> |
|||
<span style="color: #008000;">"/wiki/links/0"</span><span style="color: #0000FF;">,</span> |
|||
<span style="color: #008000;">"/wiki/links/1"</span><span style="color: #0000FF;">,</span> |
|||
<span style="color: #008000;">"/wiki/links/2"</span><span style="color: #0000FF;">,</span> |
|||
<span style="color: #008000;">"/wiki/name"</span><span style="color: #0000FF;">,</span> |
|||
<span style="color: #008000;">"/no/such/thing"</span><span style="color: #0000FF;">,</span> |
|||
<span style="color: #008000;">"bad/pointer"</span><span style="color: #0000FF;">,</span> |
|||
<span style="color: #0000FF;">}</span> |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">p</span> <span style="color: #008080;">in</span> <span style="color: #000000;">tests</span> <span style="color: #008080;">do</span> |
|||
<span style="color: #008080;">try</span> |
|||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">ptr</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">parseJSONPointer</span><span style="color: #0000FF;">(</span><span style="color: #000000;">p</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #004080;">object</span> <span style="color: #000000;">result</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">resolve</span><span style="color: #0000FF;">(</span><span style="color: #000000;">doc</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ptr</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%v -> %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">p</span><span style="color: #0000FF;">,</span><span style="color: #000000;">print_json</span><span style="color: #0000FF;">(</span><span style="color: #008000;">""</span><span style="color: #0000FF;">,</span><span style="color: #000000;">result</span><span style="color: #0000FF;">)})</span> |
|||
<span style="color: #008080;">catch</span> <span style="color: #000000;">e</span> |
|||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%v => Error %s\n\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">p</span><span style="color: #0000FF;">,</span><span style="color: #000000;">e</span><span style="color: #0000FF;">[</span><span style="color: #004600;">E_USER</span><span style="color: #0000FF;">]})</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">try</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
<!--</syntaxhighlight>--> |
|||
{{out}} |
|||
<pre> |
|||
"" -> { |
|||
"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" => Error bad index: 2 |
|||
"/wiki/name" => Error name: no such field |
|||
"/no/such/thing" => Error no: no such field |
|||
"bad/pointer" => Error pointers must start with a slash or be the empty string |
|||
</pre> |
</pre> |
||