Delphi - 在运行时创建的TXMLDocument生成AV,表单上的组件正在工作

时间:2011-12-06 10:53:49

标签: delphi delphi-2006 txmldocument

我正在运行时创建一个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

2 个答案:

答案 0 :(得分:14)

据我所知,您应该使用界面IDoc: IXMLDocument;

来自docs:

  

在没有所有者的情况下创建TXMLDocument时,它的行为类似于   接口对象。也就是说,当所有对其接口的引用都是   发布后,TXMLDocument实例会自动释放。什么时候   TXMLDocument是使用所有者创建的,但它的行为与任何行为相同   其他组件,并由其所有者释放。

换句话说,在使用TXMLDocument所有者创建nil实例时,在实例上调用Free()FreeAndNil(),并且必须将对象分配给IXMLDocument变量,以便正确管理其现在活动的引用计数。

答案 1 :(得分:2)

在运行时创建时,您需要提供OwnerTXMLDocument

XMLDocument1 := TXMLDocument.Create(xml);