JSON

Just starting out? Need help? Post your questions and find answers here.
User_Russian
Addict
Addict
Posts: 1519
Joined: Wed Nov 12, 2008 5:01 pm
Location: Russia

JSON

Post by User_Russian »

What simple method to edit JSON?
InsertJSONStructure does not fit. Data is not edited, but replaced.

Code: Select all

Structure x
  a.a
  b.s
EndStructure

Structure xx Extends x
  c.l
  d.d
EndStructure

a.x
b.xx
a\a = 20
a\b = "50"
b\a = 100
b\b = "1234"
b\c = 1000000
b\d = 10.54
If CreateJSON(0)
  InsertJSONStructure(JSONValue(0), @b, xx)
  Debug ComposeJSON(0, #PB_JSON_PrettyPrint)+~"\n\n"
  InsertJSONStructure(JSONValue(0), @a, x)
  Debug ComposeJSON(0, #PB_JSON_PrettyPrint)
EndIf
User avatar
the.weavster
Addict
Addict
Posts: 1576
Joined: Thu Jul 03, 2003 6:53 pm
Location: England

Re: JSON

Post by the.weavster »

Here are some procedures I wrote which made creating JSON a little easier (for me anyway):

Code: Select all

;-ezjson.pb
;-Just some wrappers for creating json members
;-
Procedure.i json_NewRoot()
  Static nRef
  nRef + 1
  CreateJSON(nRef)
  ProcedureReturn nRef
EndProcedure

Procedure json_FreeItem(jsr)
  If IsJSON(jsr) : FreeJSON(jsr) : EndIf
EndProcedure

Procedure.s json_PrettyPrint(jsr)
  ProcedureReturn ComposeJSON(jsr,#PB_JSON_PrettyPrint)
EndProcedure

Procedure.i json_IsInteger(txt$)
  nLen = Len(txt$)
  For i = 1 To nLen
    x$ = Mid(txt$,i,1)
    n.i = Asc(x$)
    If n < 48 Or n > 57
      ProcedureReturn #False
    EndIf
  Next i
  ProcedureReturn #True 
EndProcedure

Procedure.i json_Member(jso,key$)
  nJM = jso
  If key$ = ""
    ; we've been passed the member directly so just pass through
  Else
    ; we've been passed the parent, use the key to find/create the child
    nJM = GetJSONMember(jso,key$)
    If Not nJM
      nJM = AddJSONMember(jso,key$)
    EndIf
  EndIf
  ProcedureReturn nJM
EndProcedure

Procedure.i json_Array(jso,key$="")
  nJM = json_Member(jso,key$)
  If nJM
    SetJSONArray(nJM)
  EndIf
  ProcedureReturn nJM
EndProcedure

Procedure.i json_Boolean(jso,bval,key$="")
  nJM = json_Member(jso,key$)
  If nJM
    SetJSONBoolean(nJM,bval)
  EndIf
  ProcedureReturn nJM
EndProcedure

Procedure.i json_Double(jso,dval.d,key$="")
  nJM = json_Member(jso,key$)
  If nJM
    SetJSONDouble(nJM,dval)
  EndIf
  ProcedureReturn nJM
EndProcedure

Procedure.i json_Float(jso,fval.f,key$="")
  nJM = json_Member(jso,key$)
  If nJM
    SetJSONFloat(nJM,fval)
  EndIf
  ProcedureReturn nJM
EndProcedure

Procedure.i json_Integer(jso,ival,key$="")
  nJM = json_Member(jso,key$)
  If nJM
    SetJSONInteger(nJM,ival)
  EndIf
  ProcedureReturn nJM
EndProcedure

Procedure.i json_Null(jso,key$="")
  nJM = json_Member(jso,key$)
  If nJM
    SetJSONNull(nJM)
  EndIf
  ProcedureReturn nJM
EndProcedure

Procedure.i json_Object(jso,key$="")
  nJM = json_Member(jso,key$)
  If nJM
    SetJSONObject(nJM)
  EndIf
  ProcedureReturn nJM
EndProcedure

Procedure.i json_Quad(jso,qval.q,key$="")
  nJM = json_Member(jso,key$)
  If nJM
    SetJSONQuad(nJM,qval)
  EndIf
  ProcedureReturn nJM
EndProcedure

Procedure.i json_String(jso,sval$,key$="")
  nJM = json_Member(jso,key$)
  If nJM
    SetJSONString(nJM,sval$)
  EndIf
  ProcedureReturn nJM
EndProcedure

Procedure json_Clone(jso,jSrc,key$="")
  jDest = json_Member(jso,key$)
  Select JSONType(jSrc)
    Case #PB_JSON_Null:   
      SetJSONNull(jDest)
    Case #PB_JSON_String: 
      SetJSONString(jDest,GetJSONString(jSrc))
    Case #PB_JSON_Number:
      SetJSONDouble(jDest,GetJSONDouble(jSrc))
    Case #PB_JSON_Boolean:
      SetJSONBoolean(jDest,GetJSONBoolean(jSrc))
    Case #PB_JSON_Array:
      len = JSONArraySize(jSrc)
      SetJSONArray(jDest)
      For i = 0 To (len - 1)
        ja = GetJSONElement(jSrc,i)
        ca = AddJSONElement(jDest)
        json_Clone(ca,ja)
      Next
    Case #PB_JSON_Object:
      SetJSONObject(jDest)
      If ExamineJSONMembers(jSrc)
        While NextJSONMember(jSrc)
          k$ = JSONMemberKey(jSrc)
          jo = JSONMemberValue(jSrc)
          co = AddJSONMember(jDest,k$)
          json_Clone(co,jo)
        Wend
      EndIf
 EndSelect
EndProcedure

Procedure.i json_SearchPath(jso,pth$)
  nReps = CountString(pth$,"|") + 1
  js = jso
  For nLoop = 1 To nReps
    key$ = StringField(pth$,nLoop,"|")
    If JSONType(js) = #PB_JSON_Array
      If json_IsInteger(key$)
        If Val(key$) > JSONArraySize(js) - 1
          ProcedureReturn #False
        Else
          js = GetJSONElement(js,Val(key$))
        EndIf
      Else
        ProcedureReturn #False
      EndIf
    Else
      js = GetJSONMember(js,key$)
    EndIf
    If Not js
      ProcedureReturn #False
    EndIf
  Next
  ProcedureReturn js
EndProcedure
And here's an example of using them:

Code: Select all

XIncludeFile "ezjson.pb"

;-
;-Person methods
;-
Procedure.i Person_New(jsr,first$,last$)
  jso = json_Object(JSONValue(jsr))
  json_String(jso,first$,"firstname")
  json_String(jso,last$,"lastname")
  json_Array(jso,"offspring")
  ProcedureReturn jso
EndProcedure

Procedure Person_AddChild(pjso,cjso,takeControl=-1)
  nE = AddJSONElement(json_Member(pjso,"offspring"))
  nO = json_Object(nE)
  json_Clone(nO,cjso)
  If takeControl <> -1
    json_FreeItem(takeControl)
  EndIf
  ProcedureReturn nO
EndProcedure

Procedure.s Person_GetName(jso)
  fn$ = GetJSONString(json_Member(jso,"firstname"))
  ln$ = GetJSONString(json_Member(jso,"lastname"))
  ProcedureReturn fn$ + " " + ln$
EndProcedure

Procedure Person_SetName(jso,first$,last$)
  json_String(jso,first$,"firstname")
  json_String(jso,last$,"lastname")
EndProcedure

;-
;-Teacher methods
;-
Procedure.i Teacher_New(jsr,first$,last$,subject$)
  ; start by creating a new person
  jso = Person_New(jsr,first$,last$)
  ; and then add more members
  json_String(jso,subject$,"subject")
  ProcedureReturn jso
EndProcedure

Procedure.s Teacher_GetDetails(jso)
  ; get the Person name
  nm$ = Person_GetName(jso)
  ; and add the additional Teacher data
  sn$ = GetJSONString(json_Member(jso,"subject"))
  ProcedureReturn nm$ + ", " + sn$
EndProcedure

;-
;-And a demo of usage
;-
AbeRef = json_NewRoot()
HomerRef = json_NewRoot()
BartRef = json_NewRoot()

AbeObj = Person_New(AbeRef,"Abe","Simpson")
HomerObj = Person_New(HomerRef,"Homer","Simpson")
BartObj = Person_New(BartRef,"Bart","Simpson")

HomerObj = Person_AddChild(AbeObj,HomerObj,HomerRef) ; HomerObj now points to a sub object of AbeObj and HomerRef is freed
BartObj = Person_AddChild(HomerObj,BartObj,BartRef) ; BartObj now points to a sub object of HomerObj and BartRef is freed
Debug json_PrettyPrint(AbeRef)
Debug ""

; show we can edit the child object
Person_SetName(BartObj,"Lisa","Simpson")
Debug Person_GetName(BartObj)
Debug ""
Debug json_PrettyPrint(AbeRef)
Debug ""

; using a search path
jso = json_SearchPath(AbeObj,"offspring|0|offspring|0|firstname")
Debug GetJSONString(jso)

; create an instance of Teacher
EdnaRef = json_NewRoot()
EdnaObj = Teacher_New(EdnaRef,"Edna","Krabappel","English")
Debug Teacher_GetDetails(EdnaObj)

; because a Teacher is based on a Person
; we can pass a Teacher instance to Person methods
Debug Person_GetName(EdnaObj)

json_FreeItem(AbeRef)
json_FreeItem(EdnaRef)
User avatar
blueb
Addict
Addict
Posts: 1111
Joined: Sat Apr 26, 2003 2:15 pm
Location: Cuernavaca, Mexico

Re: JSON

Post by blueb »

User_Russian wrote:What simple method to edit JSON?
You might also look at Kenmo's "JSON_Helper.pbi"

viewtopic.php?f=13&t=65177&start=15

:)
- It was too lonely at the top.

System : PB 6.21(x64) and Win 11 Pro (x64)
Hardware: AMD Ryzen 9 5900X w/64 gigs Ram, AMD RX 6950 XT Graphics w/16gigs Mem
Little John
Addict
Addict
Posts: 4777
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: JSON

Post by Little John »

User_Russian wrote:What simple method to edit JSON?
InsertJSONStructure does not fit. Data is not edited, but replaced.
I assume that replacement happens in your code because your 1st InsertJSONStructure() uses a structure of type xx, and your 2nd InsertJSONStructure() uses a structure of a different type.
Anyway, the following code does "edit" the contents of structure xx:

Code: Select all

Structure x
  a.a
  b.s
EndStructure

Structure xx Extends x
  c.l
  d.d
EndStructure

Define b.xx

b\a = 100
b\b = "1234"
b\c = 1000000
b\d = 10.54

If CreateJSON(0)
  InsertJSONStructure(JSONValue(0), @b, xx)
  Debug ComposeJSON(0, #PB_JSON_PrettyPrint) + ~"\n\n"
  
  b\a = 20
  b\b = "50"
  InsertJSONStructure(JSONValue(0), @b, xx)
  Debug ComposeJSON(0, #PB_JSON_PrettyPrint)
EndIf
User_Russian
Addict
Addict
Posts: 1519
Joined: Wed Nov 12, 2008 5:01 pm
Location: Russia

Re: JSON

Post by User_Russian »

The problem is that JSON is a configuration file. With it work different versions of the program. In previous versions of the program, the structure has fewer fields. Because of this, compatibility is lost. After work, the previous version of the program, data is lost. The function InsertJSONStructure should edit JSON, not create from scratch.
Little John
Addict
Addict
Posts: 4777
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: JSON

Post by Little John »

User_Russian wrote:The function InsertJSONStructure should edit JSON, not create from scratch.
I don't think so. It rather seems to me that this would be a new function, say e.g. ChangeJSONStructure(). You can ask for it in the "Feature request" forum section.
User_Russian
Addict
Addict
Posts: 1519
Joined: Wed Nov 12, 2008 5:01 pm
Location: Russia

Re: JSON

Post by User_Russian »

It is not necessary to add a new function. Can add a flag #PB_JSON_NoClear like in function ExtractJSONStructure. When it is set, the contents of JSON will not clear.
Little John
Addict
Addict
Posts: 4777
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: JSON

Post by Little John »

User_Russian wrote:It is not necessary to add a new function. Can add a flag #PB_JSON_NoClear like in function ExtractJSONStructure. When it is set, the contents of JSON will not clear.
Yes, I think that's a good idea.
Post Reply