J.Parse('{"user":{"name":"Olivier"}}');
Trace(J.GetString('user.name'));
TJson is a structured-data container that holds an object, array, or scalar value. The API is built around path strings that navigate nested objects and arrays in a single expression.
| Path | Meaning |
|---|---|
"user.name" |
The name field inside the user object. |
"items[2].id" |
The id field of the third element of the items array. |
"matrix[0][3]" |
The fourth element of the first row of a 2D array. |
"" or "." |
The root document itself. |
When a SetXxx call targets a path whose parent objects do not exist yet, the missing intermediate objects are created automatically. Array indices on SetXxx, however, must already exist (use ArrayAddXxx to grow arrays).
| Procedure | Description |
|---|---|
function TJson.Create: TJson; |
Create an empty JSON document (root is an empty object). Always call Create before use. |
procedure TJson.Free; |
Release the document and all its children. Call in Destroy. |
procedure TJson.Clear; |
Reset the document to an empty object. |
function TJson.Parse(s: string): Boolean; |
Parse s into the document. Returns True on success, False on parse error. |
function TJson.AsText: string; |
Serialise the current document back to a compact JSON string. |
procedure TJson.SaveToFile(FileName: string); |
Save the document to disk as UTF-8 JSON. |
function TJson.LoadFromFile(FileName: string): Boolean; |
Load a JSON file into the document. Returns True on success. |
function TJson.Has(path: string): Boolean; |
Returns True if a value exists at path. |
function TJson.Count(path: string): integer; |
Number of items in an array or members in an object at path. |
function TJson.Count: integer; |
Same, for the root document. |
function TJson.IsArray(path: string): Boolean; |
True if the node at path is an array. |
function TJson.IsObject(path: string): Boolean; |
True if the node at path is an object. |
function TJson.GetString(path: string): string; |
Read a string value at path. Returns '' if absent. |
function TJson.GetFloat(path: string): single; |
Read a numeric value as a float. Returns 0 if absent. |
function TJson.GetInt(path: string): integer; |
Read a numeric value as an integer. Returns 0 if absent. |
function TJson.GetBool(path: string): Boolean; |
Read a boolean value at path. Returns False if absent. |
procedure TJson.SetString(path: string; val: string); |
Set a string at path, creating missing parents. |
procedure TJson.SetFloat(path: string; val: single); |
Set a numeric (float) value at path. |
procedure TJson.SetInt(path: string; val: integer); |
Set a numeric (integer) value at path. |
procedure TJson.SetBool(path: string; val: Boolean); |
Set a boolean value at path. |
procedure TJson.SetNull(path: string); |
Set a JSON null value at path. |
procedure TJson.SetObject(path: string); |
Create an empty object at path. |
procedure TJson.SetArray(path: string); |
Create an empty array at path. |
procedure TJson.Remove(path: string); |
Delete the field or array element at path. |
procedure TJson.ArrayAddString(path: string; val: string); |
Append a string element to the array at path. |
procedure TJson.ArrayAddFloat(path: string; val: single); |
Append a float element to the array at path. |
procedure TJson.ArrayAddInt(path: string; val: integer); |
Append an integer element to the array at path. |
procedure TJson.ArrayAddBool(path: string; val: Boolean); |
Append a boolean element to the array at path. |
procedure TJson.Keys(path: string; resultList: TStringList); |
Fill resultList with the keys of the object at path. |
////////////////////////////////////////////////////////////////////////////////
// TJson Methods Demo - exercises every method of the JSON API in a single
// Init pass. Open the trace window to follow the output.
////////////////////////////////////////////////////////////////////////////////
procedure Init;
var J : TJson;
SL : TStringList;
i : integer;
begin
J.Create;
// 1. parse / serialise
J.Parse('{"user":{"name":"Olivier","age":42},"tags":["a","b"]}');
Writeln('after parse: ', J.AsText);
// 2. file I/O
J.SaveToFile('config.json');
J.LoadFromFile('config.json');
// 3. read by path
Writeln('user.name = ', J.GetString('user.name')); // -> "Olivier"
Trace ('user.age = ', J.GetInt ('user.age')); // -> 42
Writeln('tags[0] = ', J.GetString('tags[0]')); // -> "a"
Trace ('tags count = ', J.Count('tags')); // -> 2
if J.Has('user.email')
then Writeln('user.email exists')
else Writeln('user.email is missing');
// 4. write by path (missing intermediates are created)
J.SetString('user.email', 'olivier@bespline.com');
J.SetFloat ('audio.gain', 0.75);
J.SetBool ('flags.muted', true);
J.SetObject('newSection');
J.SetArray ('items');
// 5. append into arrays
J.ArrayAddString('tags', 'c');
J.ArrayAddFloat ('items', 1.5);
// 6. remove
J.Remove('user.age');
J.Remove('tags[0]');
// 7. enumerate the keys of an object
SL.Create;
J.Keys('user', SL);
Writeln('keys of "user":');
for i := 0 to SL.count - 1 do
Writeln(' - ', SL.getstring(i));
SL.Free;
// 8. final state
Writeln('final: ', J.AsText);
J.Free;
end;
function TJson.Create: TJson;
Initializes the document. Always call Create before use.
J.Create;
procedure TJson.Free;
Releases the document and all its children. Call in Destroy.
procedure Destroy;
begin
J.Free;
end;
procedure TJson.Clear;
Resets the document to an empty object, freeing all current content.
J.Clear;
function TJson.Parse(s: string): Boolean;
Parses a JSON literal into the document. Returns True on success. On failure the existing document is preserved and an error is logged to the trace.
if J.Parse('{"tempo": 120, "swing": 0.5}')
then Trace('parsed ok')
else Trace('invalid JSON');
function TJson.AsText: string;
Returns a compact JSON representation of the current document. Useful for piping into a text outlet or saving manually.
jsonOut.asString(J.AsText);
procedure TJson.SaveToFile(FileName: string);
Writes the document to disk in UTF-8. Missing parent directories are created automatically.
J.SaveToFile('Scripts/state.json');
function TJson.LoadFromFile(FileName: string): Boolean;
Loads and parses a JSON file. Returns True on success. The previous document content is replaced only when the load succeeds.
if not J.LoadFromFile('Scripts/state.json')
then Trace('could not load state');
function TJson.Has(path: string): Boolean;
Tests whether the path exists in the document. Useful to guard reads on optional fields.
if J.Has('audio.gain')
then gain.asFloat(J.GetFloat('audio.gain'));
function TJson.Count(path: string): integer;
function TJson.Count: integer;
Returns the number of items in an array or members in an object at path. The parameterless overload targets the root document.
for i := 0 to J.Count('voices') - 1 do
Trace(J.GetString('voices[' + IntToStr(i) + '].name'));
function TJson.IsArray(path: string): Boolean;
function TJson.IsObject(path: string): Boolean;
Type predicates for the node at path. Use them before iterating or before navigating deeper into a structure of mixed types.
if J.IsArray('tags') then
for i := 0 to J.Count('tags') - 1 do
Trace(J.GetString('tags[' + IntToStr(i) + ']'));
function TJson.GetString(path: string): string;
function TJson.GetFloat (path: string): single;
function TJson.GetInt (path: string): integer;
function TJson.GetBool (path: string): Boolean;
Read a scalar at path. Missing or wrongly typed values return a safe default ('', 0, 0, False). Use Has first when the absence of a value is meaningful.
userName := J.GetString('user.name');
gain := J.GetFloat ('audio.gain');
voices := J.GetInt ('synth.maxVoices');
muted := J.GetBool ('flags.muted');
procedure TJson.SetString(path: string; val: string);
procedure TJson.SetFloat (path: string; val: single);
procedure TJson.SetInt (path: string; val: integer);
procedure TJson.SetBool (path: string; val: Boolean);
Write a scalar at path. Missing intermediate objects are created automatically, so a single call can deep-populate a fresh document.
J.SetString('user.name', 'Olivier');
J.SetFloat ('audio.gain', 0.75);
J.SetInt ('synth.voices', 16);
J.SetBool ('flags.muted', true);
procedure TJson.SetNull (path: string);
procedure TJson.SetObject(path: string);
procedure TJson.SetArray (path: string);
Write a JSON null, an empty object, or an empty array at path. After SetArray you can populate the array with ArrayAddXxx.
J.SetObject('audio'); // create empty container
J.SetArray ('audio.channels'); // create empty list inside it
J.SetNull ('audio.notes'); // explicit null marker
procedure TJson.Remove(path: string);
Deletes the field or array element at path. Silently does nothing when the path does not exist.
J.Remove('user.age'); // drop an object field
J.Remove('tags[0]'); // drop the first array element
procedure TJson.ArrayAddString(path: string; val: string);
procedure TJson.ArrayAddFloat (path: string; val: single);
procedure TJson.ArrayAddInt (path: string; val: integer);
procedure TJson.ArrayAddBool (path: string; val: Boolean);
Append an element to the array at path. The array must already exist (create it first with SetArray).
J.SetArray('tags');
J.ArrayAddString('tags', 'kick');
J.ArrayAddString('tags', 'snare');
J.ArrayAddInt ('tags', 808);
procedure TJson.Keys(path: string; resultList: TStringList);
Fills resultList with the keys of the object at path. The list is cleared first. Combine with Count and GetXxx to iterate dynamic objects.
var SL : TStringList;
i : integer;
begin
SL.Create;
J.Keys('user', SL);
for i := 0 to SL.count - 1 do
Trace(SL.getstring(i), ' = ', J.GetString('user.' + SL.getstring(i)));
SL.Free;
end;
Create with Free, exactly like TStringList. The script engine does not garbage-collect.SetXxx creates intermediates but ArrayAddXxx does not. Call SetArray('path.to.list') before appending elements if the array might be missing.user.Name and user.name are different keys.Parse keeps the previous content. That makes it safe to call from a Callback watching a live text inlet — bad partial input will not wipe a valid document.Process and Callback touch the same document, serialise access yourself (e.g. queue messages between them) — the same caution applies to TStringList.GetInt truncates; reading GetFloat returns a single cast.version 7.0.250121
Edit All Pages