2012-12-25 32 views
6

我在尝试访问XMLDocument的文档元素时遇到访问冲突错误。我正在根据某个文件的存在创建XMLDocument的对象。 错误消息:访问XMLDocument中的文档元素时发生访问冲突

项目PROJECT1.EXE“模块访问冲突在地址0047B152‘引发的异常类EAccessViolation与消息地址B1D59357的project1.exe'.Read’

以下是我的代码:

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. 

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

+0

代码中断在32行和根在公共部分中声明 – XPecto

+0

当我测试一个实际的XML文档时,我得到'无效指针操作'在没有特定的断点,之后构造函数完成。 –

+0

当没有XML文档并且它产生单个节点''时,代码运行正常,但是当再次运行时,它会中断任何对文档元素的读取尝试。 – XPecto

回答

4

如David所示,只需将您的XMLDocument1声明从XMLDocument1: TXMLDocument更改为XMLDocument1: IXMLDocument即可解决问题。你的问题是相关的Using TXmlDocument

+2

这不是只重复我给出的选项之一,并省略细节? –

+0

@David最初的帖子并没有提供问题的直接解决方案(只是更改XMLDocument1:IXMLDocument)。第三编辑。在第一次和第三次编辑之间张贴道歉。人们如何撤销这些东西? –

+0

原帖包含两种可能的解决方案。 –

9

您正在通过nilTXMLDocument.Create。当你这样做时,对象的行为就像TInterfacedObject。它的生命周期由接口引用计数管理。但是你没有提及一个接口。

documentation涵盖了一些细节。

当TXMLDocument创建时没有Owner,它的行为就像一个接口对象。也就是说,当所有 对其接口的引用都被释放后,TXMLDocument实例就会自动释放。但是,当使用Owner创建TXMLDocument时,它的行为与其他任何组件一样,并由其所有者释放。

如果启用调试DCU并在TXMLDocument.Destroy中设置断点,则可以在违反访问之前观察到正在销毁的对象。

解决由任一问题:

  1. 当您创建文档传递的所有者。
  2. 切换到使用接口来引用对象。这是宣布XMLDocument1IXMLDocument

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

+0

你看,我从未发现过这个。感谢上帝了解更多关于内部工作的人。 –

+0

我已经将默认构造函数更改为'构造函数创建(所有者:TObject);'并从窗体传递为'x:= TXMLbase.Create(Self);'但我有同样的问题。你能举一些例子谢谢你。 – XPecto

+0

所以不知怎的,这至少解释了一点为什么我得到一个'无效的指针操作',并且你得到了一个'访问冲突' –