I'm attempting to use the enhanced RTTI features in Delphi XE or later, to read and write objects to XML. So far I've been successful with integers, floats, strings, enumerated types, sets and classes but can't output or read records correctly. The problem seems to be getting an instance (pointer) to the record property.
//Outputs Properties To XML
procedure TMyBase.SaveToXML(node: TJclSimpleXMLElem);
var
child , subchild : TjclSimpleXMLElem ;
FContext : TRttiContext ;
FType : TRttiType ;
FProp : TRttiProperty ;
Value : TValue ;
MyObj : TMyBase ;
FField : TRttiField ;
FRecord : TRttiRecordType ;
Data : TValue ;
begin
FContext := TRttiContext.Create ;
FType := FContext.GetType ( self.ClassType ) ;
Child := node.Items.Add ( ClassName ) ;
for FProp in FType.GetProperties do begin
if FProp.IsWritable then begin
case FProp.PropertyType.TypeKind of
tkClass : begin
MyObj := TMyBase ( FProp.GetValue ( self ).AsObject ) ;
MyObj.SaveClass ( Child.Items.Add ( FProp.Name ) , FContext ) ;
end ;
tkRecord : begin
subchild := Child.Items.Add ( FProp.Name ) ;
FRecord := FContext.GetType(FProp.GetValue(self).TypeInfo).AsRecord ;
for FField in FRecord.GetFields do begin
>>> self is not the correct instance <<<
Value := FField.GetValue ( self ) ;
subchild.Items.Add ( FField.Name ).Value := Value.ToString ;
end;
end ;
else begin
Value := FProp.GetValue(self) ;
Child.Items.Add ( FProp.Name ).Value := Value.ToString ;
end;
end;
end ;
end ;
FContext.Free ;
end;
I suspect that if I can figure out how to get the values then setting them shouldn't be a problem. Then onto arrays, oh boy!
Updates: Please see below. (Migrated as separate answer to improve visibility).