dynamic-json-converter
Dynamic JSON to Object Pascal converter built from scratch using Regex. A practical solution for modernizing legacy Delphi applications.
- Quiet · last change 10-14-2024
- ★ 1 on GitHub
README
Procedure: TSomeClass.JSONToObject
This procedure maps the fields of a TJSONObject to the corresponding properties of a Delphi object (TObject). It uses RTTI (Run-Time Type Information) to dynamically access object properties and assign values from the JSON, supporting both simple types (like integers, strings, and dates) and complex types (like dynamic arrays).
Parameters:
AObject: TObject: The object instance to which the JSON data will be mapped.AJSON: TJSONObject: The JSON object containing the data that will populateAObject.
Detailed Step-by-Step Documentation:
- RTTI Context Initialization
Context := TRttiContext.Create;- The
TRttiContextis created to access metadata about the object at runtime. It enables us to retrieve information about the object's properties and methods.
- The
- Iterating Through JSON Pairs
for JsonPair in AJSON do- This loop iterates over each key-value pair in the provided
TJSONObject. EachJsonPairconsists of a key (JsonString) and a value (JsonValue).
- This loop iterates over each key-value pair in the provided
- Get Object Property
Prop := RttiType.GetProperty(JsonPair.JsonString.Value);- For each JSON key, the corresponding property of the object (
AObject) is retrieved using RTTI.RttiTyperepresents the class type of the object, andGetPropertylooks for a matching property name.
- For each JSON key, the corresponding property of the object (
- Handling Dynamic Arrays
if (Prop.PropertyType.TypeKind = tkDynArray) and (JsonPair.JsonValue is TJSONArray) then- If the property is a dynamic array and the JSON value is a JSON array (
TJSONArray), the procedure proceeds with handling arrays.
- Array Handling:
-
Initialize the Array:
SetLength(TValueArray, JsonArray.Count);The procedure creates an array (
TValueArray) ofTValuewith the same size as the JSON array.
-
-
Determine Array Element Class:
ElemClass := (Prop.PropertyType as TRttiDynamicArrayType).ElementType.AsInstance.MetaclassType;RTTI is used to retrieve the class of the elements in the dynamic array. This allows the procedure to dynamically create objects for each array element.
-
Populate Array:
SubObject := ElemClass.Create; JSONToObject(SubObject, JsonArray.Items[I] as TJSONObject); TValueArray[I] := TValue.From(SubObject);For each item in the JSON array:
- A new instance of the element class (
SubObject) is created.- The procedure recursively calls
JSONToObjectto populate the nested object with JSON data. - The object is then added to
TValueArrayas aTValue.
- The procedure recursively calls
- A new instance of the element class (
-
Assign Array to Object Property:
ArrayValue := TValue.FromArray(Prop.PropertyType.Handle, TValueArray); Prop.SetValue(AObject, ArrayValue);The dynamic array is converted to
TValueand assigned to the property of the object (AObject).
- If the property is a dynamic array and the JSON value is a JSON array (
- Handling Simple Types (Strings, Numbers, Booleans)
- If the property is not an array, the procedure handles simple data types like strings, integers, booleans, and dates.
-
Null Values:
if JsonPair.JsonValue.Null then Prop.SetValue(AObject, TValue.Empty);If the JSON value is null, the property is set to an empty value.
-
Numbers:
if Prop.PropertyType.Handle = TypeInfo(integer) then Prop.SetValue(AObject, TValue.From<integer>(TJSONNumber(JsonPair.JsonValue).AsInt))If the property is of type
integerordouble, the JSON number is converted and assigned.
-
Booleans:
if JsonPair.JsonValue is TJSONTrue then Prop.SetValue(AObject, TValue.From<Boolean>(True))JSON
trueandfalsevalues are assigned as booleans.
-
Strings:
if JsonPair.JsonValue is TJSONString then Prop.SetValue(AObject, TValue.From<string>(TJSONString(JsonPair.JsonValue).Value))If the value is a string, it is directly assigned to the property.
-
Dates:
if Prop.PropertyType.Handle = TypeInfo(TDate) then Prop.SetValue(AObject, TValue.From<TDate>(ISO8601ToDate(TJSONString(JsonPair.JsonValue).Value, False)))Strings that represent dates are converted to
TDateorTDateTimeusing theISO8601ToDatefunction and assigned.
- Unsupported Types Handling
- If the JSON value does not match a supported type, an exception is raised:
raise Exception.CreateFmt('Tipo de JSON não suportado para a propriedade "%s".', [Prop.Name]);
- If the JSON value does not match a supported type, an exception is raised:
- RTTI Context Cleanup
finally Context.Free; end;- The RTTI context is freed to release memory resources once the procedure completes.
Key Points to Consider for Maintenance:
- Recursion: The function is recursive for nested JSON objects, making it capable of handling complex data structures.
- Array Handling: Dynamic arrays require special handling due to their complex nature. Ensure that
ElemClassis correctly identified for all array elements. - Exception Handling: The procedure includes exception handling to manage invalid JSON structures and unexpected property types.
- Supported Types: The current version supports integers, doubles, booleans, strings, dates, and dynamic arrays. If you need to support additional types, extend the type-checking logic in the appropriate sections.
- RTTI Performance: While RTTI is powerful, it may introduce performance overhead in large datasets. Consider optimizing if necessary.
By following this documentation, future modifications should be easier, as each section clearly explains its purpose and behavior.

