Validate JSON string
Hi.
Is there any function to validate JSON string returning status?
Regards,
Matjaž
Comments
I'm not aware of any $ISJSON() or similar named function but you can easily make your own
ClassMethod IsJSON(str)
{
try { ret:{}.%FromJSON(str) 1 } catch e { ret:e.Code=3 0 throw e }
}
set a="{name:""John Doe"" "
set b="{""name"":""John Doe"" }"
write ##class(some.class).IsJSON(a) --> 0
write ##class(some.class).IsJSON(b) --> 1
write ##class(some.class).IsJSON() --> <UNDEFINED>zIsJSON+1^... *str
Hi.
I have used the same solution already. Tnx.
Regards, Matjaž.
This article give you an idea
https://community.intersystems.com/post/json-schema-applied-intersystem…
https://community.intersystems.com/post/function-check-if-string-json-o… another article to validate JSON string
Python may help
Class dc.Demo
{
ClassMethod ValidateJSON(data As %String = "") As %Status [ Language = python ]
{
import iris
import json
from json import JSONDecodeError
try:
json.loads(data)
return iris.system.Status.OK()
except JSONDecodeError as ex:
return iris.system.Status.Error(5001, f"{ex.msg}: line {ex.lineno} column {ex.colno} (char {ex.pos})")
except Exception as ex:
return iris.system.Status.Error(5001, repr(ex))
}
}
And result
USER>set status = ##class(dc.Demo).ValidateJSON("{""aa"":123 ""name"": ""value""}") do:'status $system.OBJ.DisplayError(status)
ERROR #5001: Expecting ',' delimiter: line 1 column 11 (char 10)
USER>set status = ##class(dc.Demo).ValidateJSON("{""aa"": true, ") do:'status $system.OBJ.DisplayError(status)
ERROR #5001: Expecting property name enclosed in double quotes: line 1 column 14 (char 13)
USER>set status = ##class(dc.Demo).ValidateJSON("{""aa"": wrong ") do:'status $system.OBJ.DisplayError(status)
ERROR #5001: Expecting value: line 1 column 8 (char 7)
USER>set status = ##class(dc.Demo).ValidateJSON("{""aa"": true}") do:'status $system.OBJ.DisplayError(status)The ##class(%DynamicAbstractObject).%FromJSON(s) class method, where 's' is a %String containing a JSON array/object or where 's' is a %Stream containing a JSON array/object, will parse the input JSON. If the parse is successful then it returns an object reference of either %DynamicArray or %DynamicObject classes. If the parse is unsuccessful then it will signal an error.
The parsing done by the %FromJSON class method is forgiving of at least one common syntax error. The input string "[0.1,.1]" is not legal JSON because the second array number does not have a digit before the decimal point. The %FromJSON class method will accept this input and silently supply the missing 0 digit. If you apply the %ToJSON() method to the resulting %DynamicArray object then the result will be the string "[0.1,0.1]", which is legal JSON syntax.
There is also a %FromJSONFile (filename) class method which will accept a JSON array/object from a file with the specified 'filename'.
May I ask, which Cache or IRIS version you use?
USER>write $zv
IRIS for UNIX (Ubuntu Server LTS for x86-64) 2021.2 (Build 649U) Thu Jan 20 2022 08:49:51 EST
USER>write ##class(%DynamicAbstractObject).%FromJSON("[0.1, .2]")
<THROW>%FromJSON+38^%Library.DynamicAbstractObject.1 *%Exception.General Parsing error 3 Line 1 Offset 7
USER 2e1>
As you see, my IRIS is by far not so forgiving... ☹
%FromJSON also accepts filenames:
set obj = {}.%FromJSON("data.json")Yes, accepts a file too, but as the following test shows, it does not make any difference... a parsing error remains parsing error
USER>set fn="/tmp/mytest.json"
USER>open fn:"nw":1 if $test { use fn write "[0.1, .2]",! close fn write "OK" } else { write "Houston, we have..." }
OK
USER>write {}.%FromJSON(fn)
<THROW>%FromJSON+38^%Library.DynamicAbstractObject.1 *%Exception.General Parsing error 3 Line 1 Offset 7
USER 2e1>
So where is that forgiving Cache/IRIS version?
2022.1.png)
%FromJSON formerly accepted file names but this was reported as a security problem where input intended to be JSON was instead interpreted as a file name, or vice-versa. As a result, recent %FromJSON method calls will not process file names but the %FromJSONFile method was added to support that case.
💡 This question is considered a Key Question. More details here.