Accessing variant JSON elements by name

Hi all,
I have a Mormot based server and I’m trying to access some JSON data using the variant’s name, but I can seem to figure out how.

This is what I currently do (Animal is a variant):

Animal := _Json (Call);
if not VarIsNull (Animal.data.Dam) then begin
   //do some stuff here
end;

What I would like to do is access the variant Animal.data fields by name. Something like this:

Animal := _Json (Call);
if not VarIsNull (VarElementByName (Animal.data, 'Dam') then begin
   //do some stuff here
end;

Does anyone have any suggestions?

Thanks in advance.

Vernon.

Hi Vernon.
What kind of client are you using to access the mORMot Server? Delphi/FPC or Javascript?
And what version of mORMot (1.18 or 2).

Also, my preferred method of dealing with JSON “Records” is to use a Client Dataset for the Web Client, and populate it from the returned JSON (there are a few different ways to do this). One nice advantage is that I can display a Grid to the user just like a normal VCL application.
If this is of interest, I can email you a Client/Server source code example.

Also, for just serialization (no dataset) I generally use mORMots TSQLRecord class and methods (serialize, deserialize). And, there’s TObject serialization. These are discussed (with some sample code) in the “Synopse mORMot Framework SAD 1.18.pdf” document (see 10. JSON Restful Client-Server). If they’re of interest then let me know. I’ve probably got samples somewhere.

If you’ll like some sample code for the Client Dataset solution, let me know here and I’ll Private Message you (and send the samples via email attachment).

I’ll be out all day today so won’t be able to send any samples untill tomorrow at the earliest.

Have you seen GitHub - falcon-sistemas/JsonToDelphi: generate delphi classes from json (Json To Delphi Class Generator / JSON Data Binding Tool FMX, VCL and uniGUI)

Thanks Robert.
I’m using Mormot 1.18, however it’s a server to server task … and to be honest it’s not really strictly a Mormot related issue.

I have no idea what the other server is, I’m simply accessing an API on the server and filling a local database with the results (parsing JSON object as a variant). The server can then serve the data as needed.

I need to access parts of the variant JSON object where I don’t know the name of the element at compile time.

Can you in any way match the JSON elements from the mistery server to the schema in your database ?
And is the JSON returned from that server consistent in terms of it’s structure, or does it vary between requests ?

I need to access parts of the variant JSON object where I don’t know the name of the element at compile time.

Sound like you need to parse the JSON to get the names of the elements.

Regards
Graeme

Oh, and if you’d like to get a clearer view of what’s coming back from that server, create and show a VCL form on your Server with a memo.
And when you get the JSON result, assign it to a RawUTF8 variable, and use memox.lines.add(myVarName) to display the returned data. Might help the matching process with your DB Schema.

Umm - I use a VCL Forms App for my servers. But I guess you might be using a console app?

Thanks Paul, but that is probably a little more complicated than I would like to go.

I would ideally like to stick with using Mormot.

Cheers.

Vernon.

1 Like

Sounds like what you are doing is similar to what I am doing except that the source mORMot server was written by me.

I am passing data back and forth using JSON and in a lot of cases the receiving code only knows that the data is in my own JSON format that contains data names along with the data values.

Regards
Graeme

Oh - and there’s (from the mORMot pdf) :

TDocVariant = class(TSynInvokeableVariantType)
A custom variant type used to store any JSON/BSON document-based content

  • i.e. name/value pairs for objects, or an array of values (including nested documents), stored in a TDocVariantData memory structure.

Lots of details/definitions in the pdf.

Looks like it could useful.

1 Like

Thanks all for the input, it was very helpful.

Robert, you hit the nail on the head regarding the TDocVariant. It has exactly the method I needed.

So I wanted something like:

Animal := _Json (Call);
if not VarIsNull (VarElementByName (Animal.data, 'Dam')) then begin
   //do some stuff here
end;

and ended up with :

Animal := _Json (Call);
if not VarIsNull (Animal.data.Value('Dam')) then begin
   //do some stuff here
end;
1 Like

Great news :-).