Access IXMLDOMDocument2 via TXMLDocument?

I have some working code using the Delphi TXMLDocument class and using the TransformNode method to perform an XSLT transform.

But I need to enable Javascript XSLT functions ( <msxml:script> ) and - after a lot of searching - this means that I need to set the AllowXsltScript IXMLDOMDocument2 to true.

http://msdn.microsoft.com/en-us/library/windows/desktop/ms760290(v=vs.85).aspx

I achieved this successfully, but only by changing the source of the Delphi CreateDOMDocument library function in msxmldom.pas .

 function CreateDOMDocument: IXMLDOMDocument; var doc :IXMLDOMDocument2; begin doc := TryObjectCreate([CLASS_DOMDocument60, CLASS_DOMDocument40, CLASS_DOMDocument30, CLASS_DOMDocument26, msxml.CLASS_DOMDocument]) as IXMLDOMDocument2; if not Assigned(doc) then raise DOMException.Create(SMSDOMNotInstalled); doc.setProperty('AllowXsltScript', true); // Allow XSLT scripts!! Result := doc; end; 

Obviously, this is far from satisfactory - so how can I access IXMLDOMDocument2 objects without changing the library code?

+4
source share
2 answers

You can override the create function with the MSXMLDOMDocumentCreate variable:

 unit Unit27; interface uses xmldoc, xmlintf, msxml, msxmldom, Forms, SysUtils, ActiveX, ComObj, XmlDom, XmlConst, Windows, Messages, Classes, Controls, StdCtrls; type TForm1 = class(TForm) procedure FormCreate(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} 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 CreateDOMDocument2: IXMLDOMDocument; var Doc2 : IXMLDOMDocument2; begin Doc2 := TryObjectCreate([CLASS_DOMDocument60, CLASS_DOMDocument40, CLASS_DOMDocument30, CLASS_DOMDocument26, msxml.CLASS_DOMDocument]) as IXMLDOMDocument2; if not Assigned(Doc2) then raise DOMException.Create(SMSDOMNotInstalled); Doc2.setProperty('AllowXsltScript', true); Result := Doc2; end; procedure TForm1.FormCreate(Sender: TObject); var Doc : IXMLDocument; begin Doc := TXMLDocument.Create(nil); Doc.LoadFromFile('c:\temp\test.xml'); end; initialization MSXMLDOMDocumentCreate := CreateDOMDocument2; end. 
+4
source

Note that in XE3 and later, MSXMLDOMDocumentCreate deprecated in favor of a subclass of TMSXMLDOMDocumentFactory and overrides its CreateDOMDocument . For future reference, here is an example of XE3 and XE4:

 interface type TMSXMLDOMDocument2Factory = class(TMSXMLDOMDocumentFactory) public class function CreateDOMDocument: IXMLDOMDocument; override; end; implementation { TMSXMLDOMDocument2Factory } class function TMSXMLDOMDocument2Factory.CreateDOMDocument: IXMLDOMDocument; begin Result := inherited; if not Assigned(Result) then raise DOMException.Create(SMSDOMNotInstalled); AddDOMProperty('AllowXsltScript', True); SetDOMProperties(Result as IXMLDOMDocument2); end; initialization MSXMLDOMDocumentFactory := TMSXMLDOMDocument2Factory; end. 
+3
source

Source: https://habr.com/ru/post/1486564/


All Articles