DWScript has built-in, high-performance support for JSON. You can easily parse JSON strings into dynamic objects or serialize native types like records and arrays into JSON.
The core of JSON support in DWScript is the JSONVariant type. It is a specialized variant that allows for late-binding and dynamic property access.
var raw := '{"id": 1, "name": "Alice", "tags": ["dev", "pascal"]}';
var data : JSONVariant := JSON.Parse(raw);
PrintLn(data.name); // Alice
PrintLn(data.tags[1]); // pascal Alice pascal
Use JSON.Parse to convert a JSON string into a JSONVariant.
var raw := '{"user": "Bob", "active": true}';
var data := JSON.Parse(raw);
if data.active then
PrintLn(data.user + ' is online'); Bob is online
Use JSON.Stringify to convert any compatible type (records, arrays, classes, variants) back to a JSON string.
You can also create empty JSON objects and arrays programmatically:
var data := JSON.NewObject;
data.name := 'Alice';
data.scores := JSON.NewArray;
data.scores.Add(10, 20, 30);
PrintLn(JSON.Stringify(data)); {"name":"Alice","scores":[10,20,30]}Records are automatically serialized based on their published fields.
For named records, you must include a published section for fields to be serialized.
type
TUser = record
published
Name: String;
Age: Integer;
end;
var u: TUser;
u.Name := 'Bob'; u.Age := 25;
PrintLn(JSON.Stringify(u)); {"Age":25,"Name":"Bob"}Anonymous records have their fields in a published section by default, making them perfect for one-off JSON objects.
var msg := record
from := 'Alice';
text := 'Hello!';
end;
PrintLn(JSON.Stringify(msg)); {"from":"Alice","text":"Hello!"}Many JSON APIs use field names that are reserved keywords in Pascal, such as type, object, or array. You can use these as field names by prefixing them with an ampersand &. When serialized to JSON, the ampersand is automatically removed.
var data := record
&type := 'Notification';
id := 101;
end;
PrintLn(JSON.Stringify(data)); {"id":101,"type":"Notification"}JSONVariant objects have built-in helper methods for manipulation. Because JSON keys can have any name, there is a potential conflict between a method name and a field name.
To resolve this, DWScript enforces a strict rule:
v.Length) to access a JSON field.() to call a built-in method (e.g., v.Length()).var v := JSON.Parse('{"Length": 500, "Defined": "yes"}');
// Field access
PrintLn(v.Length); // 500
PrintLn(v.Defined); // yes
// Method calls
PrintLn(v.Length()); // 2 (number of keys)
if v.Defined() then PrintLn('Object is defined'); 500 yes 2 Object is defined
JSONVariant supports standard array operations when it holds a JSON array.
var arr := JSON.Parse('[1, 2, 3]');
arr.Add(4);
arr.Push(5);
arr.Delete(0); // Remove first element
PrintLn(JSON.Stringify(arr));
PrintLn('Size: ' + arr.Length().ToString); [2,3,4,5] Size: 4
You can merge objects or delete keys dynamically.
var obj := JSON.NewObject;
obj.a := 1;
// Merge with another object
obj.Extend(JSON.Parse('{"b": 2, "c": 3}'));
// Delete a key
obj.Delete('a');
PrintLn(JSON.Stringify(obj)); {"b":2,"c":3}Use .TypeName() to determine the underlying JSON type.
var v := JSON.Parse('{"a": 1}');
PrintLn(v.TypeName()); // Object
PrintLn(v.a.TypeName()); // Number
if v.a.Defined() then
PrintLn('Field "a" exists'); Object Number Field "a" exists
For a complete list of all JSONVariant helper methods (such as .Clone(), .Swap(), .AsInteger(), etc.) and specialized high-performance parsers, please refer to the technical reference.