viewing XML like that of IE on Vista with TWebBrowser

1.4k views Asked by At

On XP this code worked fine if I wanted to view XML in a TWebBrowser:

uses ComObj, MSHTML, ActiveX;

procedure DocumentFromString(ABrowser: TWebBrowser; const HTMLString: wideString);
var
  v: OleVariant;
  HTMLDocument: IHTMLDocument2;
begin
  if not Assigned(ABrowser.Document) then
  begin
    ABrowser.Navigate('about:blank');
    while ABrowser.ReadyState <> READYSTATE_COMPLETE do
    begin
      Application.ProcessMessages;
      Sleep(0);
    end;
  end;
  HTMLDocument := ABrowser.Document as IHTMLDocument2;
  v := VarArrayCreate([0, 0], varVariant);
  v[0] := HTMLString;
  HTMLDocument.Write(PSafeArray(TVarData(v).VArray));
  HTMLDocument.Close;
end;

procedure WebBrowserXML(ABrowser: TWebBrowser; const XmlString: WideString);
var
  xml, xsl: OleVariant;
  HTMLString: WideString;
begin
  xml := CreateOleObject('Msxml2.DOMDocument');
  xml.async := False;
  xml.loadXML(XmlString);
  // Assert(xml.parseError.errorCode = 0);
  xsl := CreateOleObject('Msxml2.DOMDocument');
  xsl.validateOnParse := False;
  xsl.async := False;
  xsl.load('res://msxml.dll/defaultss.xsl');
  // Assert(xsl.parseError.errorCode = 0);
  HTMLString := xml.transformNode(xsl);
  ABrowser.HandleNeeded;
  DocumentFromString(ABrowser, HTMLString);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  WebBrowserXML(WebBrowser1, '<xml><node>Hello</node></xml>');
end;

The method is as followed: the XML is transformed with XSLT (defaultss.xsl) and the result is HTML.

On Vista I get an exeption in the line xml.transformNode(xsl);:

The stylesheet does not caontain a document element. The stylesheet may be empty, or it may not be a well-formed XML document

I have tried to directly load my own copy of XSLT from file like this xsl.load('my.xsl'):

http://forums.asp.net/t/1141304.aspx?xslt+viewing+XML+like+that+of+IE

but still I get the same error that the XSLT is not valid.

How do I make this code work on Vista?


From the comments to the link I provided:

I have also found that after calling directly into res://msxml#.dll/defaultss.xsl for years, this method no longer works in Vista. I've messed with all sorts of security settings, but that does not seem to be the issue. It looks like my only option is to release my own copy of defaultss.xsl.

I can't seem to provide a valid "my own copy" of defaultss.xsl. they all fail with the same exception error. what can I do?

1

There are 1 answers

0
Remy Lebeau On BEST ANSWER

The load() documentation shows an example that uses this URL:

res://msxml3.dll/xml/defaultss.xsl

If you want to embed an XSLT as a resource in your app, just make sure you use a res: URL that refers to that resource in your app. See MSDN's documentation for that syntax:

res Protocol

Syntax

res://sFile[/sType]/sID

Tokens

sFile
Percent-encoded path and file name of the module that contains the resource.

sType
Optional. String or numerical resource type. This can be either a custom resource or one of the predefined resource types that are recognized by the FindResource function. If a numerical resource type is specified, the number of the identifier must follow a # character. If this parameter is not specified, the default resource type is RT_HTML or RT_FILE.

sID
String or numerical identifier of the resource. If a numerical identifier is specified, the actual number of the identifier, not the identifier itself, must follow a # character.

I just checked on Windows 7 and msxml3.dll does have an XML resource named DEFAULTSS.XSL, but msxml4.dll and msxml6.dll do not, and there is no msxml.dll file.

As MSDN says, res: defaults to HTML or FILE if a resource type is not specified, so using res://msxml3.dll/defaultss.xls will not work since the XSLT resource type is XML instead. Thus, you need to use res://msxml3.dll/xml/defaultss.xls instead.