Page 1 of 1

Extracting JSON arrays

Posted: Tue Jan 05, 2021 5:06 pm
by Poltergeist
I'm trying to wrap my head around JSON, but find it quite difficult, to be honest. I'm probably doing it all wrong, but I have this piece of code:

Code: Select all

Declare.s GetJsonAnyValue(value)
Declare.s HTTPJsonRequest(posttype,string.s,gegevens.s="")
Declare ExtractJsonObject(value)
Declare ExtractJSONArrayValues(value)


Global json.l

Procedure.s GetJSONAnyValue(Value)
    Select JSONType(Value)
      Case #PB_JSON_Null:    ProcedureReturn "null"
      Case #PB_JSON_String:  ProcedureReturn GetJSONString(Value)
      Case #PB_JSON_Number:  ProcedureReturn StrD(GetJSONDouble(Value))    
      Case #PB_JSON_Boolean: ProcedureReturn Str(GetJSONBoolean(Value))
      Case #PB_JSON_Array:   ProcedureReturn "array"
      Case #PB_JSON_Object:  ProcedureReturn "object"
    EndSelect
  EndProcedure
  
Procedure.s HTTPJsonRequest(posttype,string.s,gegevens.s="")
  NewMap Header.s()  
  HTTPRequest=HTTPRequest(posttype,string.s,gegevens,0,header())
  If HttpRequest
    HTTPStatuscode.s=HTTPInfo(HTTPRequest, #PB_HTTP_StatusCode)
    HTTPJSONResponse.s=HTTPInfo(HTTPRequest, #PB_HTTP_Response)
    FinishHTTP(HTTPRequest)
  Else
    Debug "Request creation failed"
  EndIf
  If HTTPStatuscode="200"
    JSON=ParseJSON(#PB_Any,HTTPJSONResponse)
    If json
      ProcedureReturn ComposeJSON(json)
    Else
      ProcedureReturn "NOJSONRESPONSE"
    EndIf
  Else
    ProcedureReturn HTTPStatuscode
  EndIf
EndProcedure

Procedure ExtractJsonObject(value) ; this is an object...
  If ExamineJSONMembers(Value)
    While NextJSONMember(value)
      Debug JSONMemberKey(value)+":"+GetJSONAnyValue(JSONMemberValue(value))
      If GetJsonAnyValue(JSONMemberValue(value))="object"
        Debug "object found -------------------------------- "
        ExtractJsonObject(JSONMemberValue(value))
        Debug "End of object ------------------------------- "
      EndIf
      If GetJsonAnyValue(JSONMemberValue(value))="array"
        Debug "Array found --------------------------------- "
        ;ExtractJSONArrayValues(JSONMemberValue(value))
        Debug "End of array -------------------------------- "
      EndIf
    Wend
  EndIf
EndProcedure

Procedure ExtractJSONArrayValues(value) ; value is a jsonarray
  Debug "Arraysize:"+Str(JSONArraySize(JSONValue(value)))
  For teller=0 To JSONArraySize(JSONValue(value))-1
    Debug "teller:"+Str(teller)
    newvalue=GetJSONElement(JSONValue(value),teller)
    ExtractJsonObject(newvalue)
  Next teller
EndProcedure


InitNetwork()
APIkey.s= "apikeyverylongstring"
Debug HTTPJsonRequest(#PB_HTTP_Get,"https://user:"+apikey.s+"@api.printnode.com/printers")
ExtractJSONArrayValues(json) 
If IsJSON(json)
  FreeJSON(json)
EndIf
This results in a JSON with the following content:

Code: Select all

[{"default":false,"state":"online","createTimestamp":"2020-12-24T12:29:02.619Z","computer":{"state":"connected","inet":"10.0.6.32","createTimestamp":"2020-12-24T12:29:02.514Z","jre":null,"inet6":null,"name":"LV-ZB17G5-JP","hostname":"JP@LV-ZB17G5-JP","version":"4.24.0","id":338500},"name":"OneNote for Windows 10","capabilities":{"collate":false,"extent":[[2100,2794],[2159,2970]],"bins":["Automatisch selecteren"],"printrate":null,"medias":[],"copies":999,"dpis":["300x300"],"duplex":false,"color":true,"supports_custom_paper_size":false,"papers":{"Letter":[2159,2794],"A4":[2100,2970]},"nup":[]},"id":69957539,"description":"Microsoft Software Printer Driver"}]
There are more objects, but that's a bit much to paste them all here.

I've managed to get the values of the objects, and using recursion to get the objects in the objects. However, I don't understand how to get the arrays. I can ofcourse change these jsonarrays into arrays, but I don't know beforehand how many dimensions an array will have, and also, it makes a difference if the array is a string or a numerical value, which makes it quite hard to parse the values.

I thought I would be able to parse the JSONarray using the ExtractJSONArrayValues(value) procedure, but how do I feed the JSONarray into that procedure? I don't see any options to create a new JSON with that array...

Re: Extracting JSON arrays

Posted: Tue Jan 05, 2021 6:30 pm
by TI-994A
This tutorial illustrates creating and reading JSON values, including arrays:

> QUICK & SIMPLE TUTORIAL ON JSON FUNCTIONS

Re: Extracting JSON arrays

Posted: Fri Jan 08, 2021 3:38 pm
by Poltergeist
That's a very nice tutorial. Thank you. I've used this before (and used it as an example for my own code), but ran into the same issue with it. However, I think I will manage another way to get those arrays (if I need them)

Re: Extracting JSON arrays

Posted: Fri Jan 08, 2021 7:04 pm
by the.weavster

Code: Select all

Define JSON$ = ~"[{\"Default\":false,\"state\":\"online\",\"createTimestamp\":\"2020-12-24T12:29:02.619Z\"," +
               ~"\"computer\":{\"state\":\"connected\",\"inet\":\"10.0.6.32\",\"createTimestamp\":\"" +
               ~"2020-12-24T12:29:02.514Z\",\"jre\":null,\"inet6\":null,\"name\":\"LV-ZB17G5-JP\"," +
               ~"\"hostname\":\"JP@LV-ZB17G5-JP\",\"version\":\"4.24.0\",\"id\":338500},\"name\":\"" +
               ~"OneNote For Windows 10\",\"capabilities\":{\"collate\":false,\"extent\":" +
               ~"[[2100,2794],[2159,2970]],\"bins\":[\"Automatisch selecteren\"],\"printrate\":null," +
               ~"\"medias\":[],\"copies\":999,\"dpis\":[\"300x300\"],\"duplex\":false,\"color\":true," +
               ~"\"supports_custom_paper_size\":false,\"papers\":{\"Letter\":[2159,2794],\"A4\":[2100,2970]}," +
               ~"\"nup\":[]},\"id\":69957539,\"description\":\"Microsoft Software Printer Driver\"}]"

If ParseJSON(0, JSON$)
  Define nObject = GetJSONElement(JSONValue(0), 0)
  ; grab the capabilities object...
  Define nCapabilities = GetJSONMember(nObject, "capabilities")
  ; ...then the bin array
  Define nBins = GetJSONMember(nCapabilities, "bins")
  ; check how many elements it has
  Debug "Elements: " + Str(JSONArraySize(nBins))
  ; check out the first element
  nElement = GetJSONElement(nBins, 0)
  Select JSONType(nElement)
    Case #PB_JSON_Array
      Debug "array"
    Case #PB_JSON_Object
      Debug "object"
    Case #PB_JSON_Null
      Debug "Null"
    Case #PB_JSON_Boolean
      Debug "boolean"
      Debug GetJSONBoolean(nElement)
    Case #PB_JSON_Number
      Debug "number"
      Debug GetJSONDouble(nElement)
    Case #PB_JSON_String
      Debug "string"
      Debug GetJSONString(nElement)
  EndSelect
EndIf

If IsJSON(0)
  FreeJSON(0)
EndIf

Re: Extracting JSON arrays

Posted: Mon Jan 01, 2024 8:45 pm
by highend
I know this thread is a bit older but I was just in the need to pick specific elements in a json hierarchy so: Thank you @the.weavster for the example code to do this! :mrgreen: