Delphi - TXMLDocument, созданный во время выполнения, генерирует AV, с компонентом в форме работает
Я создаю экземпляр 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 Help:
XMLDocument1 : IXMLDocument; //not TXMLDocument
XMLDocument1 := LoadXMLDocument(...);
FreeAndNil;// must be deleted
2 ответа
Из того, что я знаю, вы должны использовать интерфейс IDoc: IXMLDocument;
вместо.
Из документов:
Когда TXMLDocument создается без владельца, он ведет себя как интерфейсный объект. То есть, когда все ссылки на его интерфейс освобождаются, экземпляр TXMLDocument автоматически освобождается. Однако когда TXMLDocument создается с владельцем, он ведет себя как любой другой компонент и освобождается его владельцем.
Другими словами, при создании TXMLDocument
экземпляр с nil
Владелец, не звоните Free()
или же FreeAndNil()
на экземпляре, и вы должны назначить объект IXMLDocument
переменная, поэтому ее теперь активный счетчик ссылок управляется правильно.
Вы должны предоставить Owner
в TXMLDocument
при создании его во время выполнения.
XMLDocument1 := TXMLDocument.Create(xml);