📄 frxxmlserializer.pas
字号:
Value: Variant;
begin
Value := GetVariantProp(Obj, PropList[i]);
s := frxStrToXML(VarToStr(Value));
end;
procedure DoClassProp;
var
FClass: TClass;
FComp: TComponent;
FObj: TPersistent;
begin
FClass := GetTypeData(PropList[i].PropType^).ClassType;
if FClass.InheritsFrom(TComponent) then
begin
FComp := TComponent(GetOrdProp(Obj, PropList[i]));
if FComp <> nil then
s := frxGetFullName(FOwner, FComp);
end
else if FClass.InheritsFrom(TPersistent) then
begin
FObj := TPersistent(GetOrdProp(Obj, PropList[i]));
if FObj is TStrings then
begin
s := TStrings(FObj).Text;
if (Length(s) >= 2) and
(s[Length(s) - 1] = #13) and (s[Length(s)] = #10) then
Delete(s, Length(s) - 1, 2);
s := ' ' + Add + PropList[i].Name + '.Text="' +
frxStrToXML(s) + '"';
end
else if FObj is TWideStrings then
begin
// skip, handle separately
end
else
s := ObjToXML(FObj, Add + PropList[i].Name + '.');
Flag := True;
end;
end;
procedure DoNonPublishedProps;
var
wr: TWriter;
ms: TMemoryStream;
begin
ms := TMemoryStream.Create;
try
wr := TWriter.Create(ms, 4096);
wr.Root := FOwner;
try
THackPersistent(Obj).DefineProperties(wr);
finally
wr.Free;
end;
if ms.Size > 0 then
begin
s := frxStreamToString(ms);
Result := Result + ' ' + Add + 'PropData="' + s + '"';
end;
finally
ms.Free;
end;
end;
begin
Result := '';
TypeInfo := Obj.ClassInfo;
PropCount := GetTypeData(TypeInfo).PropCount;
GetMem(PropList, PropCount * SizeOf(PPropInfo));
GetPropInfos(TypeInfo, PropList);
try
if Obj is TfrxComponent then
TfrxComponent(Obj).IsWriting := True;
for i := 0 to PropCount - 1 do
begin
s := '';
Flag := False;
if IsStoredProp(Obj, PropList[i]) then
case PropList[i].PropType^.Kind of
tkInteger, tkSet, tkChar, tkWChar, tkEnumeration:
DoOrdProp;
tkFloat:
DoFloatProp;
tkString, tkLString, tkWString:
DoStrProp;
tkClass:
DoClassProp;
tkVariant:
DoVariantProp;
end;
if s <> '' then
if Flag then
Result := Result + s else
Result := Result + ' ' + Add + PropList[i].Name + '="' + s + '"';
end;
if Obj is TfrxCustomMemoView then
begin
ws := TfrxCustomMemoView(Obj).Text;
if (Length(ws) >= 2) and
(ws[Length(ws) - 1] = #13) and (ws[Length(ws)] = #10) then
Delete(ws, Length(ws) - 1, 2);
Result := Result + ' Text="' + frxStrToXML(Utf8Encode(ws)) + '"';
end;
DoNonPublishedProps;
finally
if Obj is TfrxComponent then
TfrxComponent(Obj).IsWriting := False;
FreeMem(PropList, PropCount * SizeOf(PPropInfo));
end;
end;
procedure TfrxXMLSerializer.ReadRootComponent(Root: TfrxComponent;
XMLItem: TfrxXMLItem = nil; DontCreateComponents: Boolean = False);
var
XMLDoc: TfrxXMLDocument;
CompList: TList;
procedure DoRead(Item: TfrxXMLItem; Owner: TfrxComponent);
var
i: Integer;
c: TfrxComponent;
begin
try
FindClass(Item.Name);
except
FErrors.Add(frxResources.Get('xrCantFindClass') + ' ' + Item.Name);
Exit;
end;
if Owner <> nil then
begin
if DontCreateComponents then
begin
c := FOwner.FindComponent(Item.Prop['Name']) as TfrxComponent;
end
else
begin
c := TfrxComponent(FindClass(Item.Name).NewInstance);
c.Create(Owner);
end;
end
else
c := Root;
c.IsLoading := True;
XMLToObj(Item.Text, c);
CompList.Add(c);
for i := 0 to Item.Count - 1 do
DoRead(Item[i], c);
end;
procedure DoLoaded;
var
i: Integer;
c: TfrxComponent;
begin
for i := 0 to CompList.Count - 1 do
begin
c := CompList[i];
c.IsLoading := False;
if not (c is TfrxReport) then
THackComponent(c).Loaded;
end;
end;
begin
if Owner = nil then
Owner := Root;
XMLDoc := nil;
CompList := TList.Create;
if XMLItem = nil then
begin
XMLDoc := TfrxXMLDocument.Create;
XMLItem := XMLDoc.Root;
XMLDoc.LoadFromStream(FStream);
end;
FReader.Root := FOwner;
FReader.BeginReferences;
try
DoRead(XMLItem, nil);
FixupReferences;
DoLoaded;
finally
if XMLDoc <> nil then
XMLDoc.Free;
CompList.Free;
end;
end;
procedure TfrxXMLSerializer.WriteRootComponent(Root: TfrxComponent;
SaveChildren: Boolean = True; XMLItem: TfrxXMLItem = nil);
var
XMLDoc: TfrxXMLDocument;
procedure DoWrite(Item: TfrxXMLItem; ARoot: TfrxComponent);
var
i: Integer;
begin
Item.Name := ARoot.ClassName;
if ARoot = Root then
Item.Text := ObjToXML(ARoot)
else
Item.Text := 'Name="' + ARoot.Name + '"' + ObjToXML(ARoot);
if SaveChildren then
for i := 0 to ARoot.Objects.Count - 1 do
DoWrite(Item.Add, ARoot.Objects[i]);
end;
begin
if Owner = nil then
Owner := Root;
XMLDoc := nil;
if XMLItem = nil then
begin
XMLDoc := TfrxXMLDocument.Create;
XMLItem := XMLDoc.Root;
XMLDoc.AutoIndent := True;
end;
try
DoWrite(XMLItem, Root);
if XMLDoc <> nil then
XMLDoc.SaveToStream(FStream);
finally
if XMLDoc <> nil then
XMLDoc.Free;
end;
end;
function TfrxXMLSerializer.ReadComponent(Root: TfrxComponent): TfrxComponent;
var
rd: TfrxXMLReader;
RootItem: TfrxXMLItem;
begin
rd := TfrxXMLReader.Create(FStream);
RootItem := TfrxXMLItem.Create;
try
rd.ReadRootItem(RootItem, False);
Result := ReadComponentStr(Root, RootItem.Name + ' ' + RootItem.Text);
finally
rd.Free;
RootItem.Free;
end;
end;
procedure TfrxXMLSerializer.WriteComponent(c: TfrxComponent);
var
s: String;
begin
s := '<' + WriteComponentStr(c) + '/>';
FStream.Write(s[1], Length(s));
end;
function TfrxXMLSerializer.ReadComponentStr(Root: TfrxComponent;
s: String): TfrxComponent;
var
n: Integer;
s1: String;
begin
Owner := Root;
if Trim(s) = '' then
Result := nil
else
begin
n := Pos(' ', s);
s1 := Copy(s, n + 1, MaxInt);
Delete(s, n, MaxInt);
Result := TfrxComponent(FindClass(s).NewInstance);
Result.Create(Root);
FReader.Root := Root;
FReader.BeginReferences;
try
Result.IsLoading := True;
XMLToObj(s1, Result);
finally
FixupReferences;
Result.IsLoading := False;
if not (Result is TfrxReport) then
THackComponent(Result).Loaded;
end;
end;
end;
function TfrxXMLSerializer.WriteComponentStr(c: TfrxComponent): String;
begin
Result := c.ClassName + ObjToXML(c);
end;
procedure TfrxXMLSerializer.ReadPersistentStr(Root: TComponent;
Obj: TPersistent; const s: String);
begin
FReader.Root := Root;
FReader.BeginReferences;
XMLToObj(s, Obj);
FixupReferences;
end;
end.
//<censored>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -