Page 1 of 1

How to read Json results?

Posted: Wed Jan 21, 2026 1:42 pm
by RBart
Hi

I have this as a result from a download on Joplin. (jsonResult)

{"items":[{"id":"f4bfd5334d074a8ab5e414213561e1ea","parent_id":"1462c63203244ab88f5e729673ae87d1","title":"Core Zettel idee","deleted_time":0},{"id":"30e176160896445eacfdd0305e4d2f0a","parent_id":"1462c63203244ab88f5e729673ae87d1","title":"Map of content","deleted_time":0}],"has_more":true}

I looks like JSON but I don't get it, how to read it with PureBasic.

Been messing with the code examples in the help files.
But it's none of the values. Object, Array, ..
I got it as a Object by parsing but then how to get values from an jsonObject.

How do I get an understanding of this JSON handling?

Many thanks
Rudi

Code: Select all

Procedure GetJoplinNotes()
  ; Gebruik het gevalideerde endpoint voor notes
  url.s = "http://localhost:41184/notes?token=" + API_Token
  
  HttpRequest = HTTPRequest(#PB_HTTP_Get, url, "", #PB_HTTP_Asynchronous)
  If HttpRequest
    Repeat
      Progress = HTTPProgress(HttpRequest)
      Select Progress
        Case #PB_HTTP_Success
          Debug "Download voltooid"
          *Buffer = HTTPMemory(HttpRequest)
          If *Buffer
            ; Converteer buffer naar UTF-8 string
            jsonResult.s = PeekS(*Buffer, MemorySize(*Buffer),#PB_UTF8)
            
            ; Debuggen van ontvangen JSON
           ; Debug "Ontvangen JSON lengte: " + Str(Len(jsonResult)) + Chr(10)
            Debug "Eerste 1000 tekens: " + Left(jsonResult, 1000) + Chr(10)
            Debug jsonResult
           ; jsType.s=GetAnyValue(jsonRoot); number expected!!!!
           ; Debug "json objectValue type = " +  jsType ; = null dus hier is het geen JSON!!!
             
            ;GetAnyValue(jsonResult) must be a number
           ; JSON maken
            If CreateJSON(#json)
                 jsonRoot = SetJSONArray(JSONValue(0))
                  SetJSONString(AddJSONElement(jsonRoot), jsonResult);"with escaped new" + Chr(13) + Chr(10) + "line")
                  ;SetJSONString(AddJSONElement(jsonResult), "with escaped \ backslash")
                  ;Debug jsonRoot
                  Debug ComposeJSON(#json,#PB_JSON_PrettyPrint)
                  GetAnyValue(jsonRoot)
                EndIf
                
               ; Debug jsonRoot
               ; Debug JSONObjectSize(jsonRoot)
                ;jsonObject.i = ParseJSON(10, jsonRoot)
            ;Debug JSONArraySize(JSONValue(0))
            ;jsType=GetAnyValue(ComposeJSON(0)) 
            ;Debug "json jsonRoot type = " +  jsType ;
                
;             For i = 0 To JSONArraySize(JSONValue(0)) - 1
;                 Debug GetJSONInteger(GetJSONElement(JSONValue(0), i))
;             Next i
           ; Debug "Json Type: " + JSONType(jsonResult)
            ; DIT IS INGEVOEGD
;             
;              If ExamineJSONMembers(JSONValue(0))    
;                Debug "displaying JSON object members with string values only:"    
;               ; iterate through the members of the json object
;                While NextJSONMember(0)
;       
;                   ;display only members With values of string types
;                  If JSONType(JSONMemberValue(0)) = #PB_JSON_String
;             
;                     Debug "> " + JSONMemberKey(JSONValue(0)) + " = " + 
;                           GetJSONString(JSONMemberValue(0))
; 
;                  EndIf
;                 Wend
;             EndIf    
;             
            
            
            ; TOT HIER INGEVOEGD
            FreeMemory(*Buffer)
          EndIf
          FinishHTTP(HttpRequest)
          Break
          
        Case #PB_HTTP_Failed
          Debug "Download mislukt"
          FinishHTTP(HttpRequest)
          Break
      EndSelect
      Delay(100)
    ForEver
  Else
    Debug "Aanmaken request mislukt"
  EndIf
EndProcedure

Re: How to read Json results?

Posted: Wed Jan 21, 2026 1:44 pm
by NicTheQuick
You also have to use the Flag `#PB_ByteLength` for PeekS or else some characters at the end could be missing depending on the content of the data.

Re: How to read Json results?

Posted: Wed Jan 21, 2026 3:07 pm
by HeX0R
I tend to recreate the JSON structure, this makes evaluation much easier instead of using those weird JSON commands

Code: Select all

Structure myitems
	id.s
	parent_id.s
	title.s
	deleted_time.i
EndStructure

Structure BLA
	List items.myitems()
	has_more.b
EndStructure

JSON$ = ~"{\"items\":[{\"id\":\"f4bfd5334d074a8ab5e414213561e1ea\",\"parent_id\":\"1462c63203244ab88f5e729673ae87d1\",\"title\":\"Core Zettel idee\",\"deleted_time\":0},{\"id\":\"30e176160896445eacfdd0305e4d2f0a\",\"parent_id\":\"1462c63203244ab88f5e729673ae87d1\",\"title\":\"Map of content\",\"deleted_time\":0}],\"has_more\":true}"


If ParseJSON(0, JSON$)
	*Result.BLA = AllocateStructure(BLA)
	ExtractJSONStructure(JSONValue(0), *Result, BLA)
	ForEach *Result\items()
		Debug "ID: " + *Result\items()\id
		Debug "parent_id: " + *Result\items()\parent_id
		Debug "Title: " + *Result\items()\title
		Debug "Time: " + Str(*Result\items()\deleted_time)
	Next
	
	Debug "has more: " + Str(*Result\has_more)
EndIf

Re: How to read Json results?

Posted: Wed Jan 21, 2026 3:08 pm
by Paul
You could try ExtractJSONStructure ...

Code: Select all

jsonResult$=~"{\"items\":[{\"id\":\"f4bfd5334d074a8ab5e414213561e1ea\",\"parent_id\":\"1462c63203244ab88f5e729673ae87d1\",\"title\":\"Core Zettel idee\",\"deleted_time\":0},{\"id\":\"30e176160896445eacfdd0305e4d2f0a\",\"parent_id\":\"1462c63203244ab88f5e729673ae87d1\",\"title\":\"Map of content\",\"deleted_time\":0}],\"has_more\":true}"

Structure itemdata
  id.s
  parent_id.s
  title.s
  deleted_time.i
EndStructure

Structure jsondata
  List items.itemdata()
  has_more.i
EndStructure


hJSON= ParseJSON(#PB_Any, jsonResult$)
If hJSON
  ExtractJSONStructure(JSONValue(hJSON), @jd.jsondata, jsondata)  

  ForEach jd\items()
    Debug jd\items()\id
    Debug jd\items()\parent_id
    Debug jd\items()\title
    Debug jd\items()\deleted_time
    Debug "---"
  Next 

  Debug jd\has_more
          
  FreeJSON(hJSON)
EndIf

HeXOR beat me to it :P :P

Re: How to read Json results?

Posted: Wed Jan 21, 2026 3:10 pm
by Fred
would be useful to have a JSON to PB structure converter to ease this

Re: How to read Json results?

Posted: Wed Jan 21, 2026 3:17 pm
by HeX0R
Paul wrote: Wed Jan 21, 2026 3:08 pm HeXOR beat me to it :P :P
HaHaHa, two idiots, almost the very same code :mrgreen:

Re: How to read Json results?

Posted: Wed Jan 21, 2026 4:46 pm
by RBart
HeX0R wrote: Wed Jan 21, 2026 3:07 pm I tend to recreate the JSON structure, this makes evaluation much easier instead of using those weird JSON commands
How did you recreate the JSON structure? By hand?

Code: Select all

If CreateJSON(#json)
                 jsonRoot = SetJSONArray(JSONValue(0))
                  SetJSONString(AddJSONElement(jsonRoot), jsonResult);"with escaped new" + Chr(13) + Chr(10) + "line")
                  ;SetJSONString(AddJSONElement(jsonResult), "with escaped \ backslash")
                  ;Debug jsonRoot
                  jsonResult$="~" + ComposeJSON(#json,#PB_JSON_PrettyPrint)
                  Debug "after compose "+jsonResult$
                   
                EndIf
Got me something simular but not the same. And didn't work.
~[ "{\"items\":[{\"id\":\"f4bfd5334d074a8ab5e414213561e1ea\",\"parent_id\":\"1462c63203244ab88f5e729673ae87d1\",\"title\":\"Core Zettel idee\",\"deleted_time\....

Re: How to read Json results?

Posted: Wed Jan 21, 2026 5:02 pm
by RBart
Fred wrote: Wed Jan 21, 2026 3:10 pm would be useful to have a JSON to PB structure converter to ease this
In the proces what I was missing is a clear way to get the structure. In the suggested solutions the structure is already known.
It was a pain to get that. I needed to debug to see the content. The JSON code comes through an API.
Even solutions pointing in the right direction, I think, still not got it working for now.

Re: How to read Json results?

Posted: Wed Jan 21, 2026 5:15 pm
by HeX0R
RBart wrote: Wed Jan 21, 2026 4:46 pm How did you recreate the JSON structure? By hand?
Yes, took me less than 5 minutes.
But in fact your used API should have a clear description somewhere, no need to use the output and recreate the members.
Since I have no idea which service we are talking about (I don't know "joplin"), I had to use the JSON file, because that was all you gave us.
When I usually have to work with JSON from some rest API, I look into the API description to built-up the PB structures.

Re: How to read Json results?

Posted: Wed Jan 21, 2026 6:11 pm
by RBart
My json does not have back slashes. It doesn't work with the original download. The structure is not the same.

Re: How to read Json results?

Posted: Wed Jan 21, 2026 7:46 pm
by Paul
RBart wrote: Wed Jan 21, 2026 6:11 pm My json does not have back slashes. It doesn't work with the original download. The structure is not the same.
As HeXOR stated, we can only work with what you provide us and the JSON data provided translates to the structure we used.

The backslashes are only so we can post a working code snippet in the forum (they allow for the quotes to work)
If you were loading JSON data from a website it would look something like this...

Code: Select all

Structure itemdata
  id.s
  parent_id.s
  title.s
  deleted_time.i
EndStructure

Structure jsondata
  List items.itemdata()
  has_more.i
EndStructure

HttpRequest = HTTPRequest(#PB_HTTP_Get,"https://reelmedia.org/test/rbart.json")
If HttpRequest
  If HTTPInfo(HttpRequest, #PB_HTTP_StatusCode)="200"
    jsonResult$=HTTPInfo(HTTPRequest, #PB_HTTP_Response)
    
    hJSON= ParseJSON(#PB_Any, jsonResult$)
    If hJSON
      ExtractJSONStructure(JSONValue(hJSON), @jd.jsondata, jsondata)  
    
      ForEach jd\items()
        Debug jd\items()\id
        Debug jd\items()\parent_id
        Debug jd\items()\title
        Debug jd\items()\deleted_time
        Debug "---"
      Next 
    
      Debug jd\has_more
              
      FreeJSON(hJSON)
    EndIf    
  EndIf
  FinishHTTP(HttpRequest)
EndIf

Re: How to read Json results?

Posted: Wed Jan 21, 2026 11:45 pm
by kenmo
If you don't like the Structure approach 8)
you can try my JSON_Helper.pbi
https://raw.githubusercontent.com/kenmo ... Helper.pbi

Code: Select all

; https://raw.githubusercontent.com/kenmo-pb/includes/refs/heads/master/JSON_Helper.pbi
XIncludeFile "JSON_Helper.pbi"


JSONText.s = "{'items':[{'id':'f4bfd5334d074a8ab5e414213561e1ea','parent_id':'1462c63203244ab88f5e729673ae87d1','title':'Core Zettel idee','deleted_time':0},{'id':'30e176160896445eacfdd0305e4d2f0a','parent_id':'1462c63203244ab88f5e729673ae87d1','title':'Map of content','deleted_time':0}],'has_more':true}"
JSONText = ReplaceString(JSONText, "'", #DQUOTE$)

If ParseJSON(0, JSONText)
  
  *Items = JSONArrayFromPath(MainJSONObject(0), "items")
  If (*Items)
    
    N = JSONArraySize(*Items)
    For i = 0 To N-1
      *Item = GetJSONElement(*Items, i)
      Debug "title = " + JSONStringFromPath(*Item, "title")
      Debug "id = " + JSONStringFromPath(*Item, "id")
      Debug "parent_id = " + JSONStringFromPath(*Item, "parent_id")
      Debug "deleted_time = " + Str(JSONIntegerFromPath(*Item, "deleted_time"))
      Debug ""
    Next i
    
  EndIf
  
  FreeJSON(0)
EndIf

Re: How to read Json results?

Posted: Thu Jan 22, 2026 7:07 am
by TI-994A
RBart wrote: Wed Jan 21, 2026 5:02 pm...In the suggested solutions the structure is already known.
It was a pain to get that. ...
This example is from a tutorial I had posted some years ago, and it is able to extract the data from your JSON object without a predetermined structure. Simply save the JSON string into a text file and the code would read and parse it accordingly.

from this thread: PureBasic JSON: A Quick Tutorial

Code: Select all

#json = 0

Declare jsonRetrieveMembers(jsonObjectValue)
Declare jsonArrayRetrieveElements(jsonObjectValue)

Procedure jsonRetrieveMembers(jsonObjectValue)
  
  ; retrieve the json object members
  If ExamineJSONMembers(jsonObjectValue)
    
    ; iterate through the json object members 
    While NextJSONMember(jsonObjectValue)
      
      ; determine the type of value stored in the member
      jsonValueType = JSONType(JSONMemberValue(jsonObjectValue))
      
      ; retrieve the key name of the member
      jsonMemberKeyName.s = JSONMemberKey(jsonObjectValue)
      
      ; retrieve the key-value of each member according
      ; to the respective data type and display them
      If jsonValueType = #PB_JSON_String
        
        ; retrieve & display the string value of the member 
        Debug " " + jsonMemberKeyName + " = " + 
              GetJSONString(JSONMemberValue(jsonObjectValue))
        
      ElseIf jsonValueType = #PB_JSON_Number
        
        ; retrieve & display the numeric value of the member 
        Debug " " + jsonMemberKeyName + " = " + 
              GetJSONDouble(JSONMemberValue(jsonObjectValue))       
        
      ElseIf jsonValueType = #PB_JSON_Boolean
        
        ; retrieve & display the boolean value of the member 
        Debug " " + jsonMemberKeyName + " = " + 
              GetJSONBoolean(JSONMemberValue(jsonObjectValue))               
        
      ElseIf jsonValueType = #PB_JSON_Object
        
        Debug " " + jsonMemberKeyName + " = JSON Object"
        jsonRetrieveMembers(JSONMemberValue(jsonObjectValue))
        
      ElseIf jsonValueType = #PB_JSON_Array
        
        jsonArrayRetrieveElements(jsonObjectValue)
        
      EndIf      
      
    Wend
    
  EndIf
  
EndProcedure

Procedure jsonArrayRetrieveElements(jsonObjectValue)
  
  ; retrieve the key name of the member
  jsonMemberKeyName.s = JSONMemberKey(jsonObjectValue)
  
  ; get the size of the array member
  jArraySize = JSONArraySize(JSONMemberValue(jsonObjectValue))
  Debug " " + jsonMemberKeyName + " = Array of size " + Str(jArraySize)
  
  ; get the elements of the array member
  For i = 0 To (jArraySize - 1) 
    
    jsonArrayElement = GetJSONElement(JSONMemberValue(jsonObjectValue), i)
    jsonValueType = JSONType(jsonArrayElement)          
    
    If jsonValueType = #PB_JSON_String
      
      Debug " > array element " + Str(i) + " = " + GetJSONString(jsonArrayElement)
      
    ElseIf jsonValueType = #PB_JSON_Number
      
      Debug " > array element " + Str(i) + " = " + Str(GetJSONDouble(jsonArrayElement))
      
    ElseIf jsonValueType = #PB_JSON_Array
      
      Debug " > array element " + Str(i) + " = JSON Array"
      jsonArrayRetrieveElements(jsonArrayElement)
      
    ElseIf jsonValueType = #PB_JSON_Object
      
      Debug " > array element " + Str(i) + " = JSON Object"            
      jsonRetrieveMembers(jsonArrayElement)
      
    EndIf
    
  Next i  
  
EndProcedure

; load json object data from file
If LoadJSON(#json, "jsonFile.txt")
  
  Debug "all key-value data in the json object:"
  
  ; get the values of the json object
  jsonObjectValue = JSONValue(#json)
  
  jsonRetrieveMembers(jsonObjectValue)
  
  ; clear & release the json object
  FreeJSON(#json)
  
EndIf

Alternatively, instead of loading it from file, the JSON object could also be parsed directly:

Code: Select all

JSON$ = ~"{\"items\":[{\"id\":\"f4bfd5334d074a8ab5e414213561e1ea\ ... }"

; parse json object data from string
If ParseJSON(#json, JSON$)

  Debug "all key-value data in the json object:"
  
  ; get the values of the json object
  jsonObjectValue = JSONValue(#json)
  
  jsonRetrieveMembers(jsonObjectValue)
  
  ; clear & release the json object
  FreeJSON(#json)
  
EndIf

And here's the output:

Code: Select all

all key-value data in the json object:
 has_more = 1
 items = Array of size 2
 > array element 0 = JSON Object
 deleted_time = 0
 parent_id = 1462c63203244ab88f5e729673ae87d1
 title = Core Zettel idee
 id = f4bfd5334d074a8ab5e414213561e1ea
 > array element 1 = JSON Object
 deleted_time = 0
 parent_id = 1462c63203244ab88f5e729673ae87d1
 title = Map of content
 id = 30e176160896445eacfdd0305e4d2f0a

The results should ultimately be stored into some structure, or selectively into some variables, before they could viably be utilised.

I hope it helps. :D

Re: How to read Json results?

Posted: Sat Jan 24, 2026 9:20 am
by RBart
Hi,
Thanks for all these helpfull replys.
I should have given more explanaition.
Joplin is a notetaking application, offline first.
But you can synchronize over, amongst others Dropbox, Nextcloud,..
It also has an extension for the browser "Joplin web clipper" wich is a way to get information from the browser into your notetaking.
This web clipper is also a way into Joplin from other applications through it's API. This gives us options to reuse information from Joplin in our applications.
https://joplinapp.org/help/api/references/rest_api/
Thanks again,
Rudi

This worked for me, (API_Token is a variable):
Paul wrote: Wed Jan 21, 2026 7:46 pm The backslashes are only so we can post a working code snippet in the forum (they allow for the quotes to work)
If you were loading JSON data from a website it would look something like this...

Code: Select all

Procedure GetJoplinNotes()
  ; Gebruik het gevalideerde endpoint voor notes
  url.s = "http://localhost:41184/notes?token=" + API_Token 

  Structure itemdata
  id.s
  parent_id.s
  title.s
  deleted_time.i
EndStructure

Structure jsondata
  List items.itemdata()
  has_more.i
EndStructure

HttpRequest = HTTPRequest(#PB_HTTP_Get, url)
If HttpRequest
  If HTTPInfo(HttpRequest, #PB_HTTP_StatusCode)="200"    
    jsonResult$=HTTPInfo(HTTPRequest, #PB_HTTP_Response)
    
    hJSON= ParseJSON(#PB_Any, jsonResult$)
    If hJSON
      ExtractJSONStructure(JSONValue(hJSON), @jd.jsondata, jsondata)  
    
      ForEach jd\items()
        Debug jd\items()\id
        Debug jd\items()\parent_id
        Debug jd\items()\title
        Debug jd\items()\deleted_time
        Debug "---"
      Next 
    
      Debug jd\has_more
              
      FreeJSON(hJSON)
    Else
      MessageRequester("Kanban", "Gegevens konden niet opgehaald worden",#PB_MessageRequester_Error)
    EndIf  
  EndIf
  FinishHTTP(HttpRequest)
Else  
  MessageRequester("Kanban", "Geen Connectie met Joplin" + Chr(10) + "Staat Joplin en de browser open?", #PB_MessageRequester_Error)  
EndIf

EndProcedure
Next I will see if I can mix the code from TI-994A to automaticly get the structure so this could go with less code.

Greetings