Page 1 of 1
Easily validating if JSON fields exist?
Posted: Thu Jan 18, 2024 2:29 pm
by Quin
Hi,
I'm writing a networking application that uses JSON for its packet format. When trying to read any field from the JSON, I do something like this:
Code: Select all
Protected Member = GetJSONMember(JSONValue(0), "type")
If Member = 0
ProcedureReturn #False
EndIf
Protected Type = GetJSONInteger(Member)
I have a lot of JSON fields though, and this gets incredibly tedious and annoying. Is there a quicker/better way?
Thanks!
Re: Easily validating if JSON fields exist?
Posted: Thu Jan 18, 2024 3:39 pm
by boddhi
Functions such as ExtractJSONxxxx() can be used for this purpose.
Can you give a more detailed example of your JSON structure?
Re: Easily validating if JSON fields exist?
Posted: Thu Jan 18, 2024 3:45 pm
by Quin
No, ExtractJSON* I don't think will work. I get a packet like:
Code: Select all
{"type": 1, "name": "Quin", "message": "Hello world!"}
I want to get the type field if it exists, check it, and if it's 1 for example, extract the JSON fields for the name and message. But if I just extract them with GetJSONString(GetJSONMember(JSONValue(0), "name")) it crashes if the field doesn't exist. I thought about extracting to a map and using FindMapElement() but that seems almost more messy.
Re: Easily validating if JSON fields exist?
Posted: Thu Jan 18, 2024 4:08 pm
by wombats
GetJSONMember will return 0 if the member doesn't exist, so you can use it to check if a member exists, unless I'm missing something.
You can also loop through the members:
Code: Select all
Global jsonStr.s = ~"{\"type\": 1, \"name\": \"Quin\", \"message\": \"Hello world!\"}"
Global json = ParseJSON(#PB_Any, jsonStr)
Global jsonVal = JSONValue(json)
If ExamineJSONMembers(jsonVal)
While NextJSONMember(jsonVal)
Select JSONMemberKey(jsonVal)
Case "type" :
If JSONType(JSONMemberValue(jsonVal)) = #PB_JSON_Number
Debug GetJSONInteger(JSONMemberValue(jsonVal))
EndIf
Case "name"
If JSONType(JSONMemberValue(jsonVal)) = #PB_JSON_String
Debug GetJSONString(JSONMemberValue(jsonVal))
EndIf
Case "message"
If JSONType(JSONMemberValue(jsonVal)) = #PB_JSON_String
Debug GetJSONString(JSONMemberValue(jsonVal))
EndIf
EndSelect
Wend
EndIf
Re: Easily validating if JSON fields exist?
Posted: Thu Jan 18, 2024 4:10 pm
by boddhi
And this ?
Code: Select all
Structure MEMBERDETAIL
type.q
name.s
message.s
EndStructure
Define.MEMBERDETAIL Member
JSON.s="{"+Chr(34)+"type"+Chr(34)+": 1, "+Chr(34)+"name"+Chr(34)+": "+Chr(34)+"Quin"+Chr(34)+", "+Chr(34)+"message"+Chr(34)+": "+Chr(34)+"Hello world!"+Chr(34)+"}"
; UnescapeString seems corrupted on PB610bX
ParseJSON(0,JSON)
ExtractJSONStructure(JSONValue(0),@Member.MEMBERDETAIL,MEMBERDETAIL)
With Member
If \type=0 ; Or any other test
ClearStructure(@Member,MEMBERDETAIL)
Else
Debug \type
Debug \name
Debug \message
EndIf
EndWith
Re: Easily validating if JSON fields exist?
Posted: Thu Jan 18, 2024 4:44 pm
by Quin
wombats wrote: Thu Jan 18, 2024 4:08 pm
GetJSONMember will return 0 if the member doesn't exist, so you can use it to check if a member exists, unless I'm missing something.
You can also loop through the members:
Code: Select all
Global jsonStr.s = ~"{\"type\": 1, \"name\": \"Quin\", \"message\": \"Hello world!\"}"
Global json = ParseJSON(#PB_Any, jsonStr)
Global jsonVal = JSONValue(json)
If ExamineJSONMembers(jsonVal)
While NextJSONMember(jsonVal)
Select JSONMemberKey(jsonVal)
Case "type" :
If JSONType(JSONMemberValue(jsonVal)) = #PB_JSON_Number
Debug GetJSONInteger(JSONMemberValue(jsonVal))
EndIf
Case "name"
If JSONType(JSONMemberValue(jsonVal)) = #PB_JSON_String
Debug GetJSONString(JSONMemberValue(jsonVal))
EndIf
Case "message"
If JSONType(JSONMemberValue(jsonVal)) = #PB_JSON_String
Debug GetJSONString(JSONMemberValue(jsonVal))
EndIf
EndSelect
Wend
EndIf
Checking it against 0 is what I do currently, but I was wondering if there's something cleaner than having that littering my code.
Re: Easily validating if JSON fields exist?
Posted: Thu Jan 18, 2024 4:45 pm
by Quin
boddhi wrote: Thu Jan 18, 2024 4:10 pm
And this ?
Code: Select all
Structure MEMBERDETAIL
type.q
name.s
message.s
EndStructure
Define.MEMBERDETAIL Member
JSON.s="{"+Chr(34)+"type"+Chr(34)+": 1, "+Chr(34)+"name"+Chr(34)+": "+Chr(34)+"Quin"+Chr(34)+", "+Chr(34)+"message"+Chr(34)+": "+Chr(34)+"Hello world!"+Chr(34)+"}"
; UnescapeString seems corrupted on PB610bX
ParseJSON(0,JSON)
ExtractJSONStructure(JSONValue(0),@Member.MEMBERDETAIL,MEMBERDETAIL)
With Member
If \type=0 ; Or any other test
ClearStructure(@Member,MEMBERDETAIL)
Else
Debug \type
Debug \name
Debug \message
EndIf
EndWith
Oh, a structure! This is exactly what I was looking for, thanks!