免責事項: D2007 でテスト済み。
<label/>
この変更された関数に示すように 、コードは実際に XML ( ) を作成します。
function createXMLDocument(): TXMLDocument;
var
res: TXMLDocument;
rootNode: IXMLNode;
sl : TStringList;
begin
res := TXMLDocument.Create(nil);
res.Active := true;
rootNode := res.AddChild('label');
// create string for debug purposes
sl := TStringList.Create; // not needed
sl.Assign(res.XML); // Not true: sl is empty after this assignment
ShowMessage(sl.text);// sl is NOT empty!
sl.Free; // don't forget to free it! use try..finally.. to guarantee it!
//add more elements
// generateDOM(rootNode);
Result := res;
end;
しかし、それには多くの注意が必要です:
- ローカルの res 変数は必要ありません。Result を使用するだけです。
- XML を表示するために追加の StringList は必要ありません: Result.Xml.Text -作成した場合は、sl StringListを解放
する
ことを忘れないでください。
-返される XmlDocument は関数の外では使用できず、試してみると AV が返されます。
なんで?
XMLDocument は、その有効期間を管理するために、 Owner を持つ Componentとして、またはそれ以外の場合はInterfaceとして使用されることを意図しているためです。
Interface を使用して rootNode を保持すると、CreateXmlDocument 関数の最後で破棄されます。のコードを見ると、XMLDocument の所有者 (またはその参照を保持するインターフェイス) がない限り、Destroy を呼び出すトリガーが発生することがわかります。
これが、XMLDocument が有効であり、 CreateXMLDocument 関数内で設定されているのに、 Interface を返すか Owner を指定しない限り、外部では使用できない理由です。
TXMLNode._Release
TXMLDocument._Release
以下の代替ソリューションを参照してください。
function createXMLDocumentWithOwner(AOwner: TComponent): TXMLDocument;
var
rootNode: IXMLNode;
begin
Assert(AOwner <> nil, 'createXMLDocumentWithOwner cannot accept a nil Owner');
Result := TXMLDocument.Create(AOwner);
Result.Active := True;
rootNode := Result.AddChild('label');
OutputDebugString(PChar(Result.Xml.Text));
//add more elements
// generateDOM(rootNode);
end;
function createXMLDocumentInterface(): IXMLDocument;
var
rootNode: IXMLNode;
begin
Result := TXMLDocument.Create(nil);
Result.Active := True;
rootNode := Result.AddChild('label');
OutputDebugString(PChar(Result.Xml.Text));
//add more elements
// generateDOM(rootNode);
end;
procedure TForm7.Button1Click(Sender: TObject);
var
doc: TXmlDocument;
doc2: IXMLDocument;
begin
ReportMemoryLeaksOnShutdown := True;
doc := createXMLDocument;
// ShowMessage( doc.XML.Text ); // cannot use it => AV !!!!
// already freed, cannot call doc.Free;
doc := createXMLDocumentWithOwner(self);
ShowMessage( doc.XML.Text );
doc2 := createXMLDocumentInterface;
ShowMessage( doc2.XML.Text );
end;