VBA-tools/VBA-JSON

Conformance issue with JSON specification (ECMA-404)

houghtonap opened this issue · 2 comments

VBA-JSON does not conform to the ECMA-404 JSON stanadard. A valid JSON document contains a value, but VBA-JSON only allows an object or array. For example, the following are valid JSON documents:

Group 1 (success)
ParseJson("{ }").count Result 0, allowed by VBA.JSON
ParseJson("{ ""abc"": 1, ""def"": 2 }").count Result 2, allowed by VBA-JSON
ParseJson("[ ]").count Result 0, allowed by VBA-JSON
ParseJson("[ 1, 2, 3]").count Result 3, allowed by VBA-JSON

Group 2 (failure)
ParseJson("""abc""") Result Error 10001, not allowed by VBA-JSON
ParseJson("123") Result Error 10001, not allowed by VBA-JSON
ParseJson("true") Result Error 10001, not allowed by VBA-JSON
ParseJson("false") Result Error 10001, not allowed by VBA-JSON
ParseJson("null") Result Error 10001, not allowed by VBA-JSON

Supporting Group 2 in VBA-JSON is complicated. Until Group 2 is supported it is suggested that the documentation reflect that VBA-JSON only supports objects and arrays as a JSON document.

Related to this I manually added the following method to the JsonConverter module to support the reading of a JSON string. This is useful when you know the response will be a string and you can just switch to using it instead of ParseJson.

Public Function ParseJsonString(json_String As String) As String
    Dim index As Long
    index = 1
    ParseString = json_ParseString(json_String, index)
End Function

This was relatively easy to write. I haven't looked at the others.

    Dim result As String
    result = JsonConverter.ParseJsonString("""abc""")
    Rem result is "abc"

Heres ParseJsonNumber

Public Function ParseJsonNumber(json_String As String) As Variant

    Dim index As Long
    index = 1
    Rem Pad the right with whitespace so json_ParseNumber has an explicit signal
    Rem we reached end of number.
    ParseJsonNumber = json_ParseNumber(json_String + " ", index)

End Function

ParseBoolean and ParseNull can be done similarly.

Then a hacky way of closing this issue is to then use error handling to see when ParseJson fails and then call each of the primitives as I've described them. This could all then be wrapped up in a separate module or class or whatever.

I didn't spend any time looking at how to just adjust ParseJson to return a variant that could return any of the JSON types.