问题使用TXMLDocument构建XML文档 [英] Issue building an XML document using TXMLDocument

查看:125
本文介绍了问题使用TXMLDocument构建XML文档的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是delphi的新手,现在我必须阅读创建一个xml。我的代码如下:

I'm new to delphi and now I have to read create an xml. my code is the following:

function foo.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;
  sl.Assign(res.XML);// sl is empty after this assignment
  //add more elements
  generateDOM(rootNode);

  Result := res;
end;

问题是,子节点的计数增加,但res.XML为空。更不用说generateDOM过程中的其余元素似乎没有做任何事情。

The problem is, the count of child nodes increases but res.XML is empty. Not to mention that the rest of elements in the generateDOM procedure doesn't seem to be doing anything. I will be very glad with your help.

推荐答案

免责声明:用D2007进行测试。

Disclaimer: Tested with D2007.

您的代码确实创建了XML < label /> ),如修改后的函数所示:

Your code does indeed create the XML (<label/>) as shown in this modified function:

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。

- 您不需要额外的StringList来查看XML:Result.Xml.Text

- 如果您创建一个,请不要忘记免费 sl StringList。

- 返回的XmlDocument在函数外不可用,如果您尝试

But it calls for a lot of remarks:
- You don't need a local res variable, just use the Result.
- You don't need an extra StringList to see the XML: Result.Xml.Text
- Don't forget to Free the sl StringList if you create one.
- The XmlDocument you return is unusable outside the function and gives an AV if you try.

为什么?

这是因为XMLDocument旨在用作具有所有者,或作为接口,以便管理其生命周期

您使用Interface来保存rootNode的事实导致在CreateXmlDocument函数的末尾被销毁。如果你看看 TXMLNode._Release 中的代码,你会看到它触发 TXMLDocument._Release 哪个调用除非有XMLDocument的所有者(或者持有其引用的接口),否则将被破坏。

这就是为什么XMLDocument在CreateXMLDocument函数内部是有效的并且填充到之外,除非你返回界面或提供所有者

Why?
It's because an XMLDocument is intended to be used as a Component with an Owner, or as an Interface otherwise, in order to manage its lifetime.
The fact that you use an Interface to hold rootNode causes it to be destroyed at the end of the CreateXmlDocument function. And if you look at the code in TXMLNode._Release, you'll see that it triggers TXMLDocument._Release which calls Destroy unless there is an Owner for the XMLDocument (or an interface holding a reference to it).
This is why the XMLDocument is valid and populated inside the CreateXMLDocument function but not available outside it unless you return an Interface or provide an Owner.

请参阅下面的替代解决方案

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;

这篇关于问题使用TXMLDocument构建XML文档的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆