The code below has two classes, a JsonArray and a JsonObject, so we can make json objects starting from an object or an array. Parser included in both objects. Also the parser isn't recursive. The JsonObject is based on an older class named FastCollection, which use an array of a UDT and another hash array, using the HashData function of shlwapi library.
We can build a json structure, applying values, or by using a path. Also we can retrieve or update a value (and change to anoher type if we wish), using a path.
Code:
Dim k As New JsonObject
k.AssignPath "hello.0.one.3", 500
Debug.Print k.Json(4)
We get this. Array is zero based. So 3 in the path above is the fourth item
We can put null using k.nullvalue, or for arrays as in the example above, when we place an item above upper bound. For arrays, we can insert a number null values moving items up, and we can delete an number of items.
We can use the path to update the value using AssignPath statement, and we can use another format:
Code:
Dim kK as New JsonArray
kk.AssignPath "1-1-1-0", kk.anArray(0, 500), "-"
Debug.Print kk(1)(1)(1)(0)(0) ' 500
kk(1)(1)(1)(0)(0) = 8000
Debug.Print kk(1)(1)(1)(0)(0) ' 8000
We can mix JsonObjects with JsonArrays because the basic statements are the same (like a common interface).
So we can use something like this:
Code:
Debug.Print k("other key")(0)("one3")(1)
I didn't use a collection, because my fastcollection uses a hash table which is fast without using the one error statement to handle the finding procedure.
We can store any numeric type (stored on a Variant array), boolean, null, and the two objects, the JsonObject and the JsonArray. Parsing handle escape characters, and the json property render the the structure to string changing the string using escaped characters. The null value is the VBEmpty.
George
- Removing the mistake "/" with the backslash "". Thanks to wqweto, who check it.
Final Version uploaded - 7 Dec -
Last edited by georgekar; Dec 6th, 2020 at 06:52 PM.
The new version 3 handle big numbers. (also some bugs removed)
In the code posted in #1. I have two more tests. In my computer the decimal separator is "," so this version handle perfect big numbers and decimals.
Big numbers saved to Byte Arrays, inside a Variant. We have to replace the decimal separator to match those in computer, so the Val() function can convert it to a double. But if we want to get the number as string we can use ToString(), where by default convert the decimal separator to "." but optionally we can pass a second parameter, and we can choose the curdot property which is the system default character.
This is the test3, where we begin with a JsonObject
Code:
Sub test3()
Dim k As New JsonObject, a$
a$ = Replace("{'one':781263871236876287216873162873621736812763871263871263871263871263872163871326816381263e25, 'two':12390128391089012839.012892}", "'", """")
Set k = k.Parser(a$)
Debug.Print k.Json(4)
Debug.Print k("one")
Debug.Print k.ItemPath("one")
Debug.Print k("two")
Debug.Print k.ItemPath("two")
k.AssignPath "three.1", k.BigNumber("-181298328913798127981273982173892173891278921798217827389127381297323123.1234")
k.AssignPath "three.0", k.BigNumber("-1231231231231.1212")
Debug.Print k.Json(4)
Debug.Print k("three").Json
Debug.Print k("three").ToString(1)
Debug.Print k("three").ToString(0, k.DotChar)
Debug.Print k("three").ToString(0) ' always . for decimal
Set k = k.Parser(k.Json)
Debug.Print k.Json(4)
Dim vv
vv = k.BigNumber("31232131231233123.123123")
Debug.Print TypeName(vv) = "Decimal", vv
vv = k.BigNumber("31232131231233112312321312312312312123312323.123123")
Debug.Print TypeName(vv) = "Byte()", vv, Val(vv) * 2
End Sub
I run some tests, only when exponent value is more than the VB6 can handle break, return null object (typename Nothing).
If we have same keys the last value change the earlier one.
The assignpath sub and the itempath also handle keys as numbers using [ ], so [121.12] in the path string is a property name, so we can build a path like "abc.[12.12].1". When we assign a path the path always build. To test a path if exist we can use the Empty value, so k.itempath("aa.12.bc")=Empty means that we have null or not exist.