聲明:經D2007測試。
你的代碼確實創建XML(<label/>
)如本修改功能:
function createXMLDocument(): TXMLDocument;
var
res: TXMLDocument;
rootNode: IXMLNode;
sl : TStringList;
begin
res := TXMLDocument.Create(nil);
res.Active := true;
rootNode := res.AddChild('label');
// create string for debug purposes
sl := TStringList.Create; // not needed
sl.Assign(res.XML); // Not true: sl is empty after this assignment
ShowMessage(sl.text);// sl is NOT empty!
sl.Free; // don't forget to free it! use try..finally.. to guarantee it!
//add more elements
// generateDOM(rootNode);
Result := res;
end;
但它要求一個很多言論的:
- 你不需要本地res變量,只需使用Result。
- 你並不需要一個額外的StringList看到XML:Result.Xml.Text
- 如果你創建了一個不要忘記免費的SL的StringList。
- 您返回的XmlDocument在函數外部不可用,並在您嘗試使用時提供AV。
爲什麼?
這是因爲一個XMLDocument旨在被用作組分與所有者,或作爲接口否則,爲了管理其壽命。
您使用接口來保存rootNode的事實會導致它在CreateXmlDocument函數的末尾被銷燬。並且,如果您查看TXMLNode._Release
中的代碼,則會看到觸發器TXMLDocument._Release
會調用Destroy,除非XMLDocument有一個所有者(或擁有對其的引用的接口)。
這就是爲什麼XMLDocument在CreateXMLDocument函數內有效且填充的情況,但不在外部可用,除非您返回接口或提供所有者。
見替代解決方案如下:
function createXMLDocumentWithOwner(AOwner: TComponent): TXMLDocument;
var
rootNode: IXMLNode;
begin
Assert(AOwner <> nil, 'createXMLDocumentWithOwner cannot accept a nil Owner');
Result := TXMLDocument.Create(AOwner);
Result.Active := True;
rootNode := Result.AddChild('label');
OutputDebugString(PChar(Result.Xml.Text));
//add more elements
// generateDOM(rootNode);
end;
function createXMLDocumentInterface(): IXMLDocument;
var
rootNode: IXMLNode;
begin
Result := TXMLDocument.Create(nil);
Result.Active := True;
rootNode := Result.AddChild('label');
OutputDebugString(PChar(Result.Xml.Text));
//add more elements
// generateDOM(rootNode);
end;
procedure TForm7.Button1Click(Sender: TObject);
var
doc: TXmlDocument;
doc2: IXMLDocument;
begin
ReportMemoryLeaksOnShutdown := True;
doc := createXMLDocument;
// ShowMessage(doc.XML.Text); // cannot use it => AV !!!!
// already freed, cannot call doc.Free;
doc := createXMLDocumentWithOwner(self);
ShowMessage(doc.XML.Text);
doc2 := createXMLDocumentInterface;
ShowMessage(doc2.XML.Text);
end;
將是一件好事,如果你提供你正在使用的德爾福版本。在D2007的情況下查看我的答案。 – 2009-10-08 00:37:11