首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用TXMLDocument构建XML文档的问题

使用TXMLDocument构建XML文档的问题
EN

Stack Overflow用户
提问于 2009-10-07 15:27:18
回答 3查看 17.7K关注 0票数 8

我是delphi的新手,现在我必须阅读create an xml。我的代码如下:

代码语言:javascript
复制
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过程中的其他元素似乎没有做任何事情。如果能得到你的帮助,我会很高兴的。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2009-10-08 00:32:42

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

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

代码语言:javascript
复制
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变量,只需要使用结果。你不需要额外的StringList就可以看到XML: Result.Xml.Text

  • Don't

  • StringList to sl StringList if you one.
  • The XmlDocument you XmlDocument is unusable you the function and给出AV if you try

为什么?

这是因为XMLDocument旨在用作具有所有者的组件,或者用作接口,以便管理其生存期。

使用接口保存rootNode的事实会导致它在CreateXmlDocument函数结束时被销毁。如果您查看TXMLNode._Release中的代码,您将看到它触发了TXMLDocument._Release,除非XMLDocument有所有者(或包含对它的引用的接口),否则将调用Destroy。

这就是为什么XMLDocument是有效的,并且在CreateXMLDocument函数内部填充,而在它外部不可用,除非您返回一个接口或提供一个所有者。

请参阅下面的备用解决方案

代码语言:javascript
复制
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;
票数 12
EN

Stack Overflow用户

发布于 2009-10-07 17:04:55

TXMLDocument.AddChild方法的Delphi Help表示(在底部):

注意:请勿调用AddChild将子级添加到此文档的文档元素中。在向XML文档添加数据时,使用document元素的AddChild方法,或者使用层次结构中应该是新节点的父节点的节点的方法。

这就是你所做的,对吗?:-)

这是一篇关于Delphi XML Document Programming的介绍性文章,展示了如何使用TXMLDocument.DocumentElement属性,而不是在代码中定义rootnode变量。

票数 4
EN

Stack Overflow用户

发布于 2009-10-07 16:02:32

在我的类似实现中,我将res声明为IXMLDocument而不是TXMLDocument。

代码语言:javascript
复制
var
   XMLDoc: IXMLDocument;
.
.
   XMLDoc := TXMLDocument.Create(nil);
   XMLDoc.Active := True;
.
.
   XMLDoc.SaveToFile(Filename);
   XMLDoc.Active := False;
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1532353

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档