From 41b0defb54dafea0e7d5dc9dd58a51eb821cbda1 Mon Sep 17 00:00:00 2001 From: asopenag Date: Fri, 28 Dec 2018 17:57:46 +0100 Subject: [PATCH 1/2] Added support for unquoted String Values I've found lately JSONs with unquoted String values (it seems to be called [relaxed json](http://www.relaxedjson.org/)), so I've updated the code to support those: In this version, if you set the setting `JsonOptions.AllowUnquotedKeys` to `True` it will also allow unquoted Strings. Unquoted Strings (in this version) end once we find a space, a coma, a "}" or a "]". Notice that this will capture the true/false/null/numbers as strings (not having the quotes to identify the strings, all are a potential Strings), so we check them afterwards and: - If `IsNumeric()` we convert the value back to number using `VBA.Val()`. - If = "null" -> `Null` - If = "true" / "false" -> `True` / `False` **Next steps:** We should clarify the setting `JsonOptions.AllowUnquotedKeys` : (a) rename it to clarify it works for both key and values or (b) create a new setting to allow unquote key/values separately. --- JsonConverter.bas | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/JsonConverter.bas b/JsonConverter.bas index 3810579..df8b326 100644 --- a/JsonConverter.bas +++ b/JsonConverter.bas @@ -524,7 +524,24 @@ Private Function json_ParseValue(json_String As String, ByRef json_Index As Long Case """", "'" json_ParseValue = json_ParseString(json_String, json_Index) Case Else - If VBA.Mid$(json_String, json_Index, 4) = "true" Then + 'Start - Unquoted string (asopenag) ----------------------------------------------------------------------------------- + If JsonOptions.AllowUnquotedKeys Then + Dim json_Char As String + Do While json_Index > 0 And json_Index <= Len(json_String) + json_Char = VBA.Mid$(json_String, json_Index, 1) + If (json_Char <> " ") And (json_Char <> ",") And (json_Char <> "}") And (json_Char <> "]") Then + json_ParseValue = json_ParseValue & json_Char + json_Index = json_Index + 1 + Else 'once finished: + If LCase(json_ParseValue) = "true" Then json_ParseValue = True + If LCase(json_ParseValue) = "false" Then json_ParseValue = False + If LCase(json_ParseValue) = "null" Then json_ParseValue = Null + If IsNumeric(json_ParseValue) Then json_ParseValue = VBA.Val(json_ParseValue) + Exit Do + End If + Loop + 'End - Unquoted string (asopenag) ----------------------------------------------------------------------------------- + ElseIf VBA.Mid$(json_String, json_Index, 4) = "true" Then json_ParseValue = True json_Index = json_Index + 4 ElseIf VBA.Mid$(json_String, json_Index, 5) = "false" Then From fa5d902babd0abc08eec03b8b18198106d3fce64 Mon Sep 17 00:00:00 2001 From: asopenag Date: Mon, 31 Dec 2018 11:10:14 +0100 Subject: [PATCH 2/2] IsNumeric() check must be before true/false If json_ParseValue gets converted to boolean, then it returns isNumeric() -> true, leading to errors (since then true/false get converted to 0 through VBA.Val(). Now IsNumeric() check runs first, skipping that use case. --- JsonConverter.bas | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/JsonConverter.bas b/JsonConverter.bas index df8b326..2c9e85d 100644 --- a/JsonConverter.bas +++ b/JsonConverter.bas @@ -533,10 +533,10 @@ Private Function json_ParseValue(json_String As String, ByRef json_Index As Long json_ParseValue = json_ParseValue & json_Char json_Index = json_Index + 1 Else 'once finished: + If IsNumeric(json_ParseValue) Then json_ParseValue = VBA.Val(json_ParseValue) If LCase(json_ParseValue) = "true" Then json_ParseValue = True If LCase(json_ParseValue) = "false" Then json_ParseValue = False If LCase(json_ParseValue) = "null" Then json_ParseValue = Null - If IsNumeric(json_ParseValue) Then json_ParseValue = VBA.Val(json_ParseValue) Exit Do End If Loop