免责声明:使用 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 旨在用作具有 Owner 的组件,或者用作接口,以管理其生命周期。
您使用接口来保存 rootNode 的事实导致它在 CreateXmlDocument 函数结束时被销毁。如果您查看 中的代码TXMLNode._Release
,您会看到它会触发TXMLDocument._Release
调用 Destroy,除非有 XMLDocument 的所有者(或持有对它的引用的接口)。
这就是为什么 XMLDocument 在 CreateXMLDocument 函数中有效并填充但在它之外不可用的原因,除非您返回一个 Interface 或提供一个 Owner。
请参阅下面的替代解决方案:
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;