我正在运行时创建一个TXMLDocument实例,以加载和解析XML文件。您可以查看以下代码:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, xmldom, XMLIntf, msxmldom, XMLDoc, StdCtrls;
type
Txml = class(TForm)
// XMLDocument1: TXMLDocument;
Memo1: TMemo;
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
xml: Txml;
implementation
{$R *.dfm}
procedure Txml.FormCreate(Sender: TObject);
var i,j:integer;
aNode:IXMLNode;
ws:String;
XMLDocument1:TXMLDocument;
begin
Memo1.Lines.Clear;
XMLDocument1 := TXMLDocument.Create(nil);
try
XMLDocument1.LoadFromFile('C:\a.xml');
XMLDocument1.Active := true;
aNode := XMLDocument1.ChildNodes.First;
while aNode<>nil do
begin
for i := 0 to aNode.ChildNodes.Count-1 do
begin
if aNode.ChildNodes[i].NodeName = 'Role' then
begin
Memo1.Lines.Add('Tag - '+aNode.ChildNodes[i].ChildNodes['Tag'].Text);
for j := 0 to aNode.ChildNodes[i].ChildNodes.Count-1 do
if aNode.ChildNodes[i].ChildNodes[j].HasChildNodes then
begin
ws := VarToStr(aNode.ChildNodes[i].ChildNodes[j].ChildValues['Tag']);
if trim(ws)<>'' then
Memo1.Lines.Add(ws);
ws := VarToStr(aNode.ChildNodes[i].ChildNodes[j].ChildValues['Value']);
if trim(ws)<>'' then
Memo1.Lines.Add(ws);
end;
end;
end;
aNode := aNode.NextSibling;
end;
XMLDocument1.Active := false;
finally
FreeAndNil(XMLDocument1);
end;
end;
end.
问题是这会产生AV。正如您可能已经看到的那样,组件在表单上之前(// XMLDocument1:TXMLDocument;)。
为什么当组件在代码工作的表单上时,但是当我在运行时创建它时它会生成AV?
LE: 解决方案:基于答案/评论和Delphi帮助:
XMLDocument1 : IXMLDocument; //not TXMLDocument
XMLDocument1 := LoadXMLDocument(...);
FreeAndNil;// must be deleted
答案 0 :(得分:14)
据我所知,您应该使用界面IDoc: IXMLDocument;
。
来自docs:
在没有所有者的情况下创建TXMLDocument时,它的行为类似于 接口对象。也就是说,当所有对其接口的引用都是 发布后,TXMLDocument实例会自动释放。什么时候 TXMLDocument是使用所有者创建的,但它的行为与任何行为相同 其他组件,并由其所有者释放。
换句话说,在使用TXMLDocument
所有者创建nil
实例时,不在实例上调用Free()
或FreeAndNil()
,并且必须将对象分配给IXMLDocument
变量,以便正确管理其现在活动的引用计数。
答案 1 :(得分:2)
在运行时创建时,您需要提供Owner
到TXMLDocument
。
XMLDocument1 := TXMLDocument.Create(xml);