【问题标题】:Change behavior of TXMLDocument.SaveToFile更改 TXMLDocument.SaveToFile 的行为
【发布时间】:2019-09-04 17:55:09
【问题描述】:

在生产中,我们有时会遇到“拒绝访问”类型的异常。 调用堆栈来自这一行

vXML.SaveToFile(文件名);

其中 vXML 是 IXMLDocument。

这里的问题是文件名没有被记录。 我试过这个小测试程序。

implementation

uses
  xmldoc, Unit12;

{$R *.dfm}

procedure TForm11.FormShow(Sender: TObject);
const
  cnFile = 'C:\Program Files (x86)\test.xml';
var
  vXML: TAttracsXMLDoc;
begin
  vXML := TAttracsXMLDoc.Create(nil);
  try
    vXML.Active := True;
    // Process vXML
    vXML.SaveToFile(cnFile);
  finally
    vXML.Free;
  end;
end;

其他单位

unit Unit12;

interface

uses
  xmldoc,
  xml.xmldom,
  Xml.XMLIntf;

type
  TAttracsXMLDoc = class(TXMLDocument)
    procedure SaveToFile(const AFileName: DOMString); override;
  end;

implementation

uses
  Sysutils;

procedure TAttracsXMLDoc.SaveToFile(const AFileName: DOMString);
begin
  try
    inherited SaveToFile(AFileName);
  except
    on E: Exception do
    begin
      E.Message := E.Message + ' ' + AFileName + ' cannot be saved';
      raise;
    end;
  end;
end;

end.

它按预期工作。但问题是接口 IXMLDocument 不再使用。我想使用这样的代码:

procedure TForm11.FormShow(Sender: TObject);
const
  cnFile = 'C:\Program Files (x86)\test.xml';
var
  vXML: IXMLDocument;
begin
  vXML := NewXMLDocument;
  // Process vXML
  vXML.SaveToFile(cnFile);
end;

并且对现有代码进行最小更改即可捕获上述异常,并带有明显的原因错误。最好的路径是什么?

【问题讨论】:

  • 如果我没记错的话,如果在构造函数中将所有者作为 NIL 传递,XMLDocument 就会出现问题。
  • @dummzeuch 它不是“参差不齐”,该行为已被完整记录。当构造一个 nil 所有者时,它充当接口对象,并且必须分配给接口变量以维持生命周期。当使用非零所有者构造时,它充当所有者管理生命周期的普通拥有对象。无论哪种方式,这都不会影响文档的功能,只会影响其生命周期
  • @RemyLebeau 我知道记录在案的行为,不幸的是这还没有结束。每当我尝试通过 NIL 时,我都会遇到非常奇怪的错误,即使我只将生成的实例用作接口。如果没有,不胜感激,调试起来真是腰疼。
  • @dummzeuch 我从未听说过 XMLDocument 在节点/文件处理方面的行为不同,具体取决于它是否具有 nil 所有者。
  • 现在你有...

标签: delphi exception delphi-xe


【解决方案1】:

只需将NewXMLDocument() 替换为TAttracsXMLDoc,就会得到你想要的行为:

function NewAttracsXMLDocument: IXMLDocument;
begin
  Result := TAttracsXMLDoc.Create(nil);
end;

procedure TForm11.FormShow(Sender: TObject);
const
  cnFile = 'C:\Program Files (x86)\test.xml';
var
  vXML: IXMLDocument;
begin
  vXML := NewAttracsXMLDocument; //NewXMLDocument;
  // Process vXML
  vXML.SaveToFile(cnFile);
end;

【讨论】:

  • 谢谢,不知道.Create可以返回接口
  • @RolandBengtsson 它没有。但是它返回的对象确实实现了一个接口,所以可以赋值给一个接口变量
猜你喜欢
  • 1970-01-01
  • 2011-05-20
  • 2023-03-18
  • 1970-01-01
  • 2016-05-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多