在XMLDocument中使用DocumentElement时发生访问冲突

XPe*_*cto 7 delphi xmldocument

当我尝试使用我总是得到一个访问冲突DocumentElementXMLDocument.我XMLDocument根据一些文件的存在创建.

错误信息

项目project1.exe引发异常类EAccessViolation,消息'模块'地址0047B152中的访问冲突'project1.exe'.地址B1D59357'

我的代码

unit XMLBase;

interface
uses
  SysUtils, xmldom, XMLIntf, XMLDoc, Forms;

type
  TXMLbase = class
  private
    { Private declarations }
  public
    XMLDocument1: TXMLDocument;
    root: IXMLNode;    
    constructor Create;
  end;

var
  fn: string;

implementation

constructor TXMLbase.Create;
begin   
  fn := ChangeFileExt(Application.ExeName, '.xml');
  XMLDocument1 := TXMLDocument.Create(nil);
  XMLDocument1.Options := [doNodeAutoIndent];
  XMLDocument1.Active := False;
  //optional, is used to indent the Xml document
  if FileExists(fn) then
  begin
  XMLDocument1.LoadFromFile(fn);
  XMLDocument1.Active:= True;
  root := XMLDocument1.DocumentElement;  //<<--- Access Voilation
  end
  else
  begin
    XMLDocument1.Active := False;
    XMLDocument1.XML.Text := '';
    XMLDocument1.Active := True;
    root := XMLDocument1.AddChild('Settings');    
  end;
XMLDocument1.SaveToFile(fn);
end;

end.
Run Code Online (Sandbox Code Playgroud)

由于对象或指针初始化不正确而导致访问冲突,这是否意味着XMLDocument未初始化?

Dav*_*nan 10

要传递nilTXMLDocument.Create.执行此操作时,对象的行为类似于TInterfacedObject.它的生命周期由接口引用计数管理.但是你没有持有对接口的引用.

文档详细介绍了这一点.

在没有所有者的情况下创建TXMLDocument时,它的行为类似于接口对象.也就是说,当释放对其接口的所有引用时,将自动释放TXMLDocument实例.但是,当使用所有者创建TXMLDocument时,它的行为与任何其他组件一样,并由其所有者释放.

如果启用调试DCU并设置断点,则TXMLDocument.Destroy可以在访问冲突之前观察被销毁的对象.

通过以下任一方法解决问题:

  1. 在创建文档时传递所有者.
  2. 切换到使用接口来引用对象.这被声明XMLDocument1IXMLDocument.

确保你做其中一个,但不是两个!

  • 那还不够!你必须将所有者传递给`TXMLDocument`构造函数!像这样:`XMLDocument1:= TXMLDocument.Create(Owener)`. (2认同)

Jac*_* G. 3

正如 David 所指出的,只需将 XMLDocument1 声明从 更改为XMLDocument1: TXMLDocument即可XMLDocument1: IXMLDocument解决问题。您的问题与使用 TXmlDocument有关

  • 这不是重复了我给出的选项之一,而省略了细节吗? (3认同)