03-22-2023, 10:11 PM
(03-22-2023, 05:28 AM)grymmjack Wrote: Then you could use like:
Code: (Select All)shapes[*].name
to get the names back as an array of strings (bad example but maybe you get my meaning?)
Yes I know exactly what you're talking about. I definitely consider it something that would be nice to add somehow, the underlying issues are that the query logic gets a lot more complicated, and the resulting token will end up being something that does not exist in the original JSON structure.
For that second part, currently queries only return tokens that already exist, but your query would require making a new array token for the result. That's doable (just call
JsonTokenCreateArray()and fill it in) but then what's the lifetime of that token and how does it get free'd? We could just leak it until
JsonClearis called but that's a bit ugly, and also means
Jsonobjects would keep growing in size as you query them.
That said right now you can totally write your own helper functions to do this sort of transformation and manage the extra tokens yourself (this code is completely untested):
Code: (Select All)
resultNames& = splat(j, JsonQuery(j, "shapes"), "name")
resultSides& = splat(j, JsonQuery(j, "shapes"), "sides")
Function splat&(j As Json, arr As Long, query As String)
Dim newArr As Long, child As Long, count As Long, i As Long
newArr = JsonTokenCreateArray(j)
count = JsonTokenTotalChildren(j, arr)
For i = 0 to count - 1
JsonTokenArrayAdd j, newArr, JsonQueryFrom(j, JsonTokenGetChild(j, arr, i), query)
Next
splat& = newArr
End Function
That array then either sticks around until you do a
JsonClear, or could be free'd manually before that with
JsonTokenFreeShallow. And to be clear, that's definitely not as nice as just being able to pass it to a
JsonQuery()and get a result, but writing some helper functions like that can be a pretty effective way to simplify your parsing, especially if there's some common patterns in your JSON.
Note that the above code still doesn't quite work for your example because the
"name"is inside of other objects with different keys. Also, you can't have direct key-value pairs inside an array It would work for something like this though (keys removed):
Code: (Select All)
{
"shapes": [
{
"name": "Simple Square",
"sides": 4
},
{
"name": "Just a Triangle",
"sides": 3
},
{
"name": "Line is just 2 points",
"sides": 0,
"points": 2
},
{
"name": "Here we have 1 point for origin of Circle",
"sides": 0,
"points": 1,
"radius": 100
}
]
}