I would like to save my array of objects (arr) into json file from Beckhoff TwinCAT3 using FB_JsonDomParser
. This is what I want to get:
{ 'MyArray' : [{a: 1, b: 0.4}, {a: 3, b: 9.1}, {a: 6, b: 0.1}] }
This is my attempt, where I couldn't find anything suitable within push methods.
fbJson : FB_JsonDomParser;
jRoot : SJsonValue;
jArray : SJsonValue;
bSaveJsonFile : BOOL;
arr : ARRAY[0..9] OF MYSTRUCT; // structure contains int and real
jRoot := fbJson.NewDocument();
jArray := fbJson.AddArrayMember(jRoot, 'MyArray', 0);
// not sure how to add objects here into jArray
fbJson.SaveDocumentToFile(sFile := 'C:\tmp\test.json', bExec := bSaveJsonFile);
Not a user of json in TwinCAT, but I played around a bit and created what you are looking for, though I used FB_JsonSaxWriter
and FB_JsonReadWriteDataType
, let me know if this helps. This could be encapsulated as a function or a method that could be used for generics instead of using specific data type like here, but it should serve as a sufficient example imho.
Here is the code:
PROGRAM MAIN
VAR
arr : ARRAY [0..3] OF ST_MyDataType := [
(realVal := 0.0, intVal := 0),
(realVal := 1.0, intVal := 1),
(realVal := 2.0, intVal := 2),
(realVal := 3.0, intVal := 3)];
bWriteToFile : BOOL;
bWriteSuccess : BOOL;
nArrayIteration : UDINT;
fbJsonDataType : FB_JsonReadWriteDataType;
fbJsonWriter : FB_JsonSaxWriter;
fbJson : FB_JsonDomParser;
sJsonDoc : STRING(2000);
bCreateJsonDoc : BOOL;
END_VAR
IF bCreateJsonDoc THEN
bCreateJsonDoc := FALSE;
fbJsonWriter.ResetDocument();
fbJsonWriter.StartObject();
fbJsonWriter.AddString('My array of structures');
// Start the array
fbJsonWriter.StartArray();
// Iterate the array's objects here
FOR nArrayIteration := 0 TO SIZEOF(arr)/SIZEOF(ST_MyDataType) - 1 BY 1 DO
// Create an object and the values based on the current iteration of the array
fbJsonDataType.AddJsonValueFromSymbol(
fbjsonwriter,
'ST_MyDataType',
SIZEOF(ST_MyDataType),
ADR(arr) + nArrayIteration*SIZEOF(ST_MyDataType));
// Object end (all struct members written)
END_FOR
// End the array and create the json doc as a string to be written
fbJsonWriter.EndArray();
fbJsonWriter.EndObject();
fbJsonWriter.CopyDocument(sJsonDoc, SIZEOF(sJsonDoc));
fbJson.ParseDocument(sJsonDoc);
END_IF
bWriteSuccess := fbJson.SaveDocumentToFile(
bExec := bWriteToFile,
sFile := 'C:\JsonTest\Test.json');
Here is the resulting json doc content:
{"My array of structures":[{"realVal":0.0,"intVal":0},{"realVal":1.0,"intVal":1},{"realVal":2.0,"intVal":2},{"realVal":3.0,"intVal":3}]}
And here is the data type definition:
TYPE ST_MyDataType :
STRUCT
realVal : REAL;
intVal : INT;
END_STRUCT
END_TYPE
Edit:
I did try to use only FB_JsonDomParser
but I didn't manage to add Base64Object, it always ended up looking weird. I could add normal objects to array (int, bool, etc...), but when calling FB_JsonDomParser.PushbackBase64Value(jsonSetArrayObject, ADR(stTest), SIZEOF(stTest));
my result would end up looking like this:
You can clearly see adding booleans works, but adding base 64 as a stand alone member or to be pushed to the array did not work - as mentioned, no experience on this subject, perhaps someone else can give some more valuable input.