Workaround for the "AllowDocumentFunction constraint violated" error with Delphi XE2 apps

I have been reading discussions online about an EOleException error we were getting when calling TransformNode from a Delphi XE2 application: "Operation Aborted: AllowDocumentFunction constraint violated". The problem arises because Delphi XE2 now uses MSXML 6.0, which has made some changes to default settings for security reasons.

This, along with the ProhibitDTD property, has caused some grief. The recommended fix is to make changes to the VCL unit xml.win.msxmldom.pas. I found an alternative which appears to work without side-effects and requires no changes to the VCL source code: set the MSXMLDOMDocumentCreate to your own custom implementation which sets the AllowDocumentFunction (and ProhibitDTD or AllowXsltScript if you wanted) property after creating the object.

unit msxml_transformnode_fix;

interface

implementation

uses
  Winapi.ActiveX, Winapi.Windows, System.Variants, System.Win.ComObj, Winapi.msxml, Xml.xmldom, System.Classes,
  Xml.Win.msxmldom, Xml.XMLConst;

function TryObjectCreate(const GuidList: array of TGuid): IUnknown;
var
  I: Integer;
  Status: HResult;
begin
  Status := S_OK;
  for I := Low(GuidList) to High(GuidList) do
  begin
    Status := CoCreateInstance(GuidList[I], nil, CLSCTX_INPROC_SERVER or
      CLSCTX_LOCAL_SERVER, IDispatch, Result);
    if Status = S_OK then Exit;
  end;
  OleCheck(Status);
end;

function CreateDOMDocument: IXMLDOMDocument;
begin
  Result := TryObjectCreate([CLASS_DOMDocument60, CLASS_DOMDocument40, CLASS_DOMDocument30,
    CLASS_DOMDocument26, Winapi.msxml.CLASS_DOMDocument]) as IXMLDOMDocument;
  if not Assigned(Result) then
    raise DOMException.Create(SMSDOMNotInstalled);

  try
    (Result as IXMLDOMDocument2).SetProperty('AllowDocumentFunction', True);
  except on E: EOleError do
    ;
  end;
end;

initialization
  MSXMLDOMDocumentCreate := msxml_transformnode_fix.CreateDOMDocument;
end.

Leave a Reply

Your email address will not be published.