I think if you need a dynamic way to extract data use Tpersistent + to store the data. If you need 1 to manny use TCollection. (http://www.delphi3000.com/articles/article_1844.asp?SK=)
I wrote a article on how to get data from and to the GUI http://www.delphi3000.com/articles/article_1846.asp?SK= This shows how to use RTTI I think this all works in Lazarus. Something like this is also implemeted in the RTTI tab of Lazarus. Streaming object to a XML File (and retrieving them) should not be hard to implement based on the RTTI routines. So all you need to do is to create at least a TPersistant with your fields published that can be read by RTTI and so iterated in e general function. Heres some code I found on how to make XML form a object. You will need to rewrite it im sure. procedure TXMLBaseParcer.MakeXmlFromPersistent(APersistent: TPersistent; Parentname: string; ABaseNode: TjanXMLNode); var PropList: PPropList; PropCount: Integer; ClassTypeInfo: PTypeInfo; ClassTypeData: PTypeData; i, EnumCount, CollectionCount: integer; Propname: string; ANode, AddedNode: TjanXMLNode; begin if APersistent = nil then exit; AddedNode := nil; ClassTypeInfo := APersistent.ClassInfo; ClassTypeData := GetTypeData(ClassTypeInfo); PropCount := ClassTypeData.PropCount - 1; // reserveer geheugen GetMem(PropList, SizeOf(PPropInfo) * ClassTypeData.PropCount); // Error trap try // Vul de prop list GetPropInfos(APersistent.ClassInfo, PropList); if Parentname <> '' then ANode := ABaseNode.SelectSingleNode(UnderscoresToName(Parentname)) else ANode := ABaseNode; if ANode <> nil then for i := 0 to PropCount do begin Propname := Parentname + '_' + PropList[i]^.Name; if Propname[1] = '_' then Propname[1] := ' '; Propname := trim(Propname); case PropList[i]^.PropType^.Kind of tkString, tkLString, tkWString, tkWChar, tkChar: begin if (APersistent is tcomponent) and (PropList[i]^.Name = 'Name') then AddedNode := nil else AddedNode := ANode.AddNode(PropList[i]^.Name, GetStrProp(APersistent, PropList[i])); end; tkInteger, tkEnumeration: begin if (PropList[i]^.PropType^.Name = 'Boolean') then begin if GetOrdProp(APersistent, PropList[i]) = 0 then AddedNode := ANode.AddNode(PropList[i]^.Name, false) else AddedNode := ANode.AddNode(PropList[i]^.Name, true); end else AddedNode := ANode.AddNode(PropList[i]^.Name, GetOrdProp(APersistent, PropList[i])); end; tkFloat: begin if (PropList[i]^.PropType^.Name = 'TDateTime') then begin AddedNode := ANode.AddNode(PropList[i]^.Name, VarFromDateTime(GetFloatProp(APersistent, PropList[i]))) end else AddedNode := ANode.AddNode(PropList[i]^.Name, GetFloatProp(APersistent, PropList[i])); end; tkClass: begin if GetObjectProp(APersistent, PropList[i]) is TPersistent then begin AddedNode := ANode.AddNode(PropList[i]^.Name, ''); if GetObjectProp(APersistent, PropList[i]) is TCollection then begin for CollectionCount := 0 to TCollection(GetObjectProp(APersistent, PropList[i])).Count - 1 do begin AddedNode.AddNode('OBJ' + IntToStr(CollectionCount), null); MakeXmlFromPersistent(TPersistent(TCollection(GetObjectProp(APersistent, PropList[i])).Items[CollectionCount]), Propname + '_' + 'OBJ' + IntToStr(CollectionCount), ABaseNode); end; end; MakeXmlFromPersistent(TPersistent(GetObjectProp(APersistent, PropList[i])), Propname, ABaseNode); end; end; tkArray: begin end; end; // end case if TypeInfo and (AddedNode <> nil) then begin case PropList[i]^.PropType^.Kind of tkString, tkLString, tkWString, tkWChar, tkChar: AddedNode.AddAttribute('Type', 'String'); tkInteger: AddedNode.AddAttribute('Type', 'Number'); tkEnumeration: begin AddedNode.AddAttribute('Type', 'Enum'); for EnumCount := GetTypeData(PropList[i]^.PropType^).MinValue to GetTypeData(PropList[i]^.PropType^).MaxValue do AddedNode.AddAttribute(GetEnumName(PropList[i]^.PropType^, EnumCount), IntToStr(EnumCount)); end; tkFloat: begin if (PropList[i]^.PropType^.Name = 'TDateTime') then AddedNode.AddAttribute('Type', 'Date') else AddedNode.AddAttribute('Type', 'Float'); end; tkClass: begin if GetObjectProp(APersistent, PropList[i]) is TCollection then AddedNode.AddAttribute('Type', 'Collection') else AddedNode.AddAttribute('Type', 'Class'); end; end; end; end; // end i finally FreeMem(PropList, SizeOf(PPropInfo) * ClassTypeData.PropCount); end; end; procedure TXMLBaseParcer.SetXmlToPersistent(APersistent: TPersistent; Parentname: string; ABaseNode: TjanXMLNode); var PropList: PPropList; PropCount, CollCount, NummerNode: Integer; ClassTypeInfo: PTypeInfo; ClassTypeData: PTypeData; i: integer; TempString: string; Propname: string; ANode: TjanXMLNode; ADate: TDate; begin if APersistent = nil then exit; ClassTypeInfo := APersistent.ClassInfo; ClassTypeData := GetTypeData(ClassTypeInfo); PropCount := ClassTypeData.PropCount - 1; // reserveer geheugen GetMem(PropList, SizeOf(PPropInfo) * ClassTypeData.PropCount); // Error trap try // Vul de prop list GetPropList(APersistent.ClassInfo, tkAny, PropList); for i := 0 to PropCount do begin Propname := Parentname + '_' + PropList[i]^.Name; if Propname[1] = '_' then Propname[1] := ' '; Propname := trim(Propname); ANode := ABaseNode.SelectSingleNode(UnderscoresToName(Propname)); try if (Anode <> nil) then case PropList[i]^.PropType^.Kind of tkString, tkLString, tkWString, tkWChar, tkChar: begin if (APersistent is tcomponent) and (PropList[i]^.Name = 'Name') then else if (assigned(PropList[i]^.SetProc)) then SetStrProp(APersistent, PropList[i], VarToStr(Anode.Value)); end; tkInteger, tkEnumeration: begin if (VarToStr(ANode.Value) = 'True') or (VarToStr(ANode.Value) = 'False') then // if vartype(ANode.Value) = varBoolean then begin if (assigned(PropList[i]^.SetProc)) then if ANode.Value = true then SetOrdProp(APersistent, PropList[i], 1) else SetOrdProp(APersistent, PropList[i], 0); end else begin Tempstring := VarToStr(ANode.Value); if Tempstring <> '' then begin if (assigned(PropList[i]^.SetProc)) then SetOrdProp(APersistent, PropList[i], StrToInt(Tempstring)); end; end; end; tkFloat: begin if VarToStr(ANode.Value) <> '' then if (assigned(PropList[i]^.SetProc)) then if (PropList[i]^.PropType^.Name = 'TDateTime') then begin ADate := VarToDateTime(ANode.Value); SetFloatProp(APersistent, PropList[i], ADate); end else begin SetFloatProp(APersistent, PropList[i], StrTOFLoat(VarToStr(ANode.Value))); end; end; tkClass: begin if GetObjectProp(APersistent, PropList[i]) is TPersistent then begin if GetObjectProp(APersistent, PropList[i]) is TCollection then begin with GetObjectProp(APersistent, PropList[i]) as TCollection do begin if fMapCollections then begin NummerNode := 0; for CollCount := 0 to Count - 1 do begin if ANode.SelectSingleNode('OBJ' + IntToStr(NummerNode)) <> nil then begin SetXmlToPersistent(Items[Collcount], Propname + '_' + 'OBJ' + IntToStr(NummerNode), ABaseNode); Inc(NummerNode); end; end; end else // no map collections begin clear; NummerNode := 0; if UseBeterCollectionSupport then begin //if ANode.SelectSingleNode(PropList[i]^.Name) <> nil then for CollCount := 0 to ANode.Nodes.Count - 1 do begin if Uppercase(TJanXmlNode(ANode.Nodes[CollCount]).Name) = Uppercase(PropList[i]^.PropType^.Name) then begin SetXmlToPersistent(Add, '' , ANode.indexNode[CollCount]); end; end; end else begin for CollCount := 0 to ANode.Nodes.Count - 1 do begin if ANode.SelectSingleNode('OBJ' + IntToStr(NummerNode)) <> nil then begin SetXmlToPersistent(Add, Propname + '_' + 'OBJ' + IntToStr(NummerNode), ABaseNode); Inc(NummerNode); end; end; end; // alternate collection add end end; // end with end; //end is collection SetXmlToPersistent(TPersistent(GetObjectProp(APersistent, PropList[i])), Propname, ABaseNode); end; end; tkArray: begin Showmessage('Set array ' + PropList[i]^.Name); end; end; // end case except on e: Exception do end; end; finally FreeMem(PropList, SizeOf(PPropInfo) * ClassTypeData.PropCount); end; end; Met vriendelijke groet, Pieter Valentijn Delphidreams http://www.delphidreams.nl -----Oorspronkelijk bericht----- Van: Bram Kuijvenhoven [mailto:[EMAIL PROTECTED] Verzonden: zondag 18 maart 2007 22:05 Aan: [email protected] Onderwerp: Re: [lazarus] XML and Record type George Lober wrote: > A question guys. Are there any utilities/functions out there to > convert > a pascal record type into XML format and back? Is there such an animal, > or am I asking for too much? Not for as far as I known, but I think you could either - use classes with published methods & RTTI; there might already be some code dealing with this; have a look at TXMLPropStorage - write a program that parses the record declaration and produces XML read/write functions for these record types Regards, Bram _________________________________________________________________ To unsubscribe: mail [EMAIL PROTECTED] with "unsubscribe" as the Subject archives at http://www.lazarus.freepascal.org/mailarchives _________________________________________________________________ To unsubscribe: mail [EMAIL PROTECTED] with "unsubscribe" as the Subject archives at http://www.lazarus.freepascal.org/mailarchives
