Luiz Henrique C... · Mar 5, 2021

How i can process a JSON


I am making a request to an API and JSON is coming as follows:

SET %httprequest = ##class(%Net.HttpRequest).%New()
DO %httprequest.Get(URL)
SET %responseBody = %httprequest.HttpResponse.Data.Read()

W %responseBody
{produto:"CHP0001",Local:{IDMV: "000000001",LOTE: "",DtFabric: "null",DtVenc: "null",Atributo06: "0000000002",Atributo07: "",QtdeDisp: "10.00000",QtdeAloc: "0.00000",QtdeSep: "0.00000",QtdeTotal: "10.00000",Status: "OK",Motivo: ""}}

ZW %responseBody
%responseBody="{produto:""CHP0001"",Local:{IDMV: ""000000001"",LOTE: """",DtFabric: ""null"",DtVenc: ""null"",Atributo06: ""0000000002"",Atributo07: """",QtdeDisp: ""10.00000"",QtdeAloc: ""0.00000"",QtdeSep: ""0.00000"",QtdeTotal: ""10.00000"",Status: ""OK"",Motivo: """"}}"

and I'm trying to create a dynamic object:
SET obj = ##class(%DynamicAbstractObject).%FromJSON(%responseBody)

but an error happens:
<THROW>%FromJSON+37^%Library.DynamicAbstractObject.1 *%Exception.General Parsing error 3 Line 1 Offset 2

I tried to include double quotes in the keys using $ TR, I even tried to use charset, but without success!I tried to include double quotes in the keys using $ TR, I even tried to use charset, but without success!

can anybody help me? sad



Product version: Caché 2018.1
2 0 9 126
Log in or sign up to continue


You can pass a stream to JSON parser. So, this code should work

SET obj = {}.%FromJSON(%httprequest.HttpResponse.Data)

ahh, you have a just a wrong JSON, I would recommend to find a way how to fix it from the side where it comes from.

Key names in the JSON also have to be wrapped by quotes

Try this

Set json = "{produto:""CHP0001"",Local:{IDMV: ""000000001"",LOTE: """",DtFabric: ""null"",DtVenc: ""null"",Atributo06: ""0000000002"",Atributo07: """",QtdeDisp: ""10.00000"",QtdeAloc: ""0.00000"",QtdeSep: ""0.00000"",QtdeTotal: ""10.00000"",Status: ""OK"",Motivo: """"}}" 

DO ##class(%ZEN.Auxiliary.jsonProvider).%ConvertJSONToObject(json,"",.pObject,"") 

zw pObject

pObject=18@%ZEN.proxyObject ; <OREF>
+----------------- general information ---------------
| oref value: 18
| class name: %ZEN.proxyObject
| reference count: 2
+----------------- attribute values ------------------
| %changed = 1
| %data("Local") = "16@%ZEN.proxyObject"
| %data("produto") = "CHP0001"
| %index = ""

This method does not appear to be used in this version 2018.1

%ZEN.Auxiliary.jsonProvider class and %ConvertJSONToObject method are definitely available in 2018.1. They are available on way older versions - 2014.1 at least and probably older.

That said, in 2018.1 it would be better to use %ZEN.Auxiliary.altJSONProvider - it has the same methods but uses dynamic objects instead of %ZEN.proxyObject which is faster.

this is exactly what I needed, thank you very much for your help! laugh

how could I do it in array cases inside the Json object?

{produto:"CHP0001",Local:[{IDMV: "000000001",LOTE: "",DtFabric: "null",DtVenc: "null",Atributo06: "0000000002",Atributo07: "",QtdeDisp: "10.00000",QtdeAloc: "0.00000",QtdeSep: "0.00000",QtdeTotal: "10.00000",Status: "OK",Motivo: ""}]}

DO ##class(%ZEN.Auxiliary.jsonProvider).%ConvertJSONToObject(json,"",.pObject,"")
pObject=<OBJECT REFERENCE>[7@%ZEN.proxyObject]
+----------------- general information ---------------
|      oref value: 7
|      class name: %ZEN.proxyObject
| reference count: 3
+----------------- attribute values ------------------
|           %changed = 1
|     %data("Local") = "6@%Library.ListOfObjects"
|   %data("produto") = "CHP0001"
|             %index = ""

if i, ZW pObject.produto -> "CHP0001" 
OK, but!

ZW pObject.Local
<OBJECT REFERENCE>[6@%Library.ListOfObjects]
+----------------- general information ---------------
|      oref value: 6
|      class name: %Library.ListOfObjects
| reference count: 4
+----------------- attribute values ------------------
|            Data(1) = ""
|        ElementType = "%RegisteredObject"
|            Oref(1) = "5@%ZEN.proxyObject"
|               Size = 1  <Set>

how can I get the values ​​contained in the array now?

Hello Luiz, to manipulate the list, you must use

zw pObject.Local.GetAt (1)


For i=1:1:pObject.Local.Size


 w pObject.Local.GetAt(i)