Querying JSON with SelectToken

interop
dotnet
json
Tags: #<Tag:0x00007f46dc1184e0> #<Tag:0x00007f46dc118350> #<Tag:0x00007f46dc1181e8>

#1

For some time I have been using an UnmanagedExports wrapper around JsonTextReader and JsonTextWriter from Json.NET which was quite handy but had limitations.

Today I have added the ability to Querying JSON with SelectToken which so far is pretty damn awesome!

Consider this JSON data for input:

{
    "solutions": [
        {
            "departureTime": "08:24",
            "rego": "ABC123",
        },
       {
            "departureTime": "09:24",
            "rego": "ZZZ321",
        }
    ]
}

I can do things like this:

  Json.InitJObject(jsonData)
  i=-1 ! remember zero based arrays in .NET
  LOOP
    i+=1
    vehicleRego = Json.SelectToken('solutions[' & i & '].rego')
    IF vehicleRego = ''
      ! We are done with the solutions, see ya!
      BREAK
    END
    Debug.Message('Vehicle Rego: ' & vehicleRego)
  END
  Json.KillJObject()

Of course at the moment it considers everything a string on the .NET side and relies on Clarion data conversions which might bite me at some point but I image you could do something like Json.SelectToken('solutions[0].ChildSomething[22].MoneyField', EQUATE_TYPE:DECIMAL) and add a bit of handling on the other end to deal with different data types or whatever.

Anyway, I thought is was pretty cool and worth a share. With this I can react to incoming Json data in a very dynamic way without lots of pain. Yay!


Clarion 6.3 and JSon Consumption
#2

Hi Brahn.

Looks good. I’m a bit confused that your links go to the Json.NET site, but your code here is in Clarion? Are you developing a Clarion class as well?

I noticed that your check if there are elements s[i].rego left, is whether the value it returns is blank. Wouldn’t that cause a problem when the actual value is a blank string? Because Clarion doesn’t have a native NULL value, maybe you can add a property to your Json class to indicate that the SelectToken could not find the value, maybe a property called Error that returns an error when an operation failed?


#3

Correct. I create a .NET class that “exports” methods that I can call from Clarion. If you look for unmanaged or dllexport here you should get the idea. You can use them from the Clarion side by creating a LIB from the DLL or ,my preference, use LoadLibrary.

Yeah, in my particular use case this was not going to be a concern. Maybe something like this would work:

CASE Json.SelectTokenResult('solutions[' & i & '].rego') 
OF JSON_EQUATE:NULL
  Stop('SelectToken response was NULL' )
OF JSON_EQUATE:ERROR
  Stop('SelectToken says: ' & Json.GetLastError())
ELSE
  Stop('SelectToken found: ' & Json.GetCurrentValue())
END