Rendering an XML stream

With XML/XSL adding such great capabilities for formatting output I would like to be able to stream XML data into a CHTMLView.  While the XSL sheet can reside in the program directory, the XML is produced dynamically as output from various calculations with the view rendering it in the same way that it does if you load an xml document from the local drive.  Is it possible to insert items into an XML document and have it render (using the XSL sheet) as each element is added as with HTML? Can anyone show me a way of going about this?

Regards

David
RupreckAsked:
Who is Participating?
 
DanRollinsConnect With a Mentor Commented:
First, let's not forget the obvious:  You can simply dump the XML to a temporary file on the hard disk, then display it.  That is the cleanest and simplest solution and the one least likely to cause problems.  If you want to do it that way, and don't know how, just ask.

That said, if you really need to avoid the temporary-file, then try loading XML text from memory using the same techniques that can be used to feed HTML into an CHtmlView.  To wit:

Here's the easiest way:
#include <mshtml.h>
#include <atlbase.h>

CString gsHtmlPage="This is some body text <b>from memory</b>!";

void CSdiHtmlView::OnDocumentComplete(LPCTSTR lpszURL)
{
    CHtmlView::OnDocumentComplete(lpszURL);

   HRESULT hr;
   IHTMLDocument2*  spDoc= (IHTMLDocument2*)GetHtmlDocument();
   IHTMLElement*    pElem= NULL;

   hr= spDoc->get_body( &pElem ); // prolly ought to do some error checking
   CComBSTR bstrHtml= gsHtmlPage;
   hr= pElem->put_innerHTML( bstrHtml );  // set the body text
}
=-=-=-=-=-=-=-=-=-
First navigate to some page (eg, about:blank) then the above code kicks in.  

=-=-=-=-=-=-=-=-=-
Here's another way:

To display a very short page, you can use the
about:
protocol.  For instance:

Navigate("about:"<html><body>This page was loaded from <b>memory!</b></body></html>", 0,0,0 );

=-=-=-=-=-=-=-=-=-
There is another way that is more complicated, involving creating a stream from a memory block:

// include <HTML><BODY> with this technique
CString gsHtmlPage="<HTML><BODY>This is some body text <b>from memory</b>!</body></html>";

void CSdiHtmlView::OnDocumentComplete(LPCTSTR lpszURL)
{
   static BOOL fDoneOnce= FALSE; // reentrancy kludge
   if ( fDoneOnce ) {
       fDoneOnce= FALSE;
       return;
   }
   fDoneOnce= TRUE;

   IPersistStreamInit* pPersistStreamInit= NULL;

   DWORD nPgLen= gsHtmlPage.GetLength();
   HRESULT hr;
   HGLOBAL hMemPage=  GlobalAlloc( GPTR, nPgLen+1 );
   LPSTR   pMemPage=  (LPSTR)GlobalLock( hMemPage );
   memcpy( pMemPage, (LPCSTR)gsHtmlPage, nPgLen+1 );
   GlobalUnlock( hMemPage );

   LPSTREAM pStm;
   hr= CreateStreamOnHGlobal( hMemPage, TRUE, &pStm );
   if( SUCCEEDED(hr) ) {
       LPDISPATCH pHtmlDoc= GetHtmlDocument();
       if ( pHtmlDoc ) {
           hr= pHtmlDoc->QueryInterface( IID_IPersistStreamInit, (void**)&pPersistStreamInit );
           hr= pPersistStreamInit->InitNew();  // Initialize it with the storage we created
           hr= pPersistStreamInit->Load( pStm );
       }
   }
   if( pPersistStreamInit ) {
       pPersistStreamInit->Release();
   }
   GlobalFree( hMemPage );
}

-- Dan
0
 
RupreckAuthor Commented:
Hi Dan,
Thanks very much for your suggestions however I have some bad news to report.  All these methods work well with HTML however not with XML.

1) Method 1
I already knew the first method and unfortunately it seems to not be able to trigger the XML engine in IE to kick in or something and this may be part of the .innerHTML() command.  After loading about:blank and then this XML string:

gsHtmlPage =  "<?xml version=\"1.0\" standalone=\"no\"?>\r\n";
gsHtmlPage += "<xml-stylesheet type=\"text/xsl\" href=\"olssamp.xsl\">\r\n";
gsHtmlPage += "<!-- Here begins the XML data -->\r\n";
gsHtmlPage += "<OUTPUT>\r\n";
gsHtmlPage += "<METHOD ID=\"OLS\">\r\n";
gsHtmlPage += "<COMMAND>OLS CONSUME INCOME PRICE / ANOVA PCOV</COMMAND>\r\n";
gsHtmlPage += "</METHOD>\r\n";
gsHtmlPage += "</OUTPUT>";


the resultant output on the screen is a plain black:

OLS CONSUME INCOME PRICE / ANOVA PCOV

i.e. the default behaviour for unrecognised HTML tags has them ignored and the remainder of the text simply outputted.  However when making that block into a file and double clicking it to load in IE the associated style sheet (correctly) turns this command blue.  Style sheet is placed in all the appropriate directories.

2) Method 2
This method automatically inserts the tags <HTML> </HTML> around the text fooling the XML engine.  This time the text does not appear.  Removing the 'about:' makes the problem worse.

3) Method 3
Again a blank page.  Right clicking to 'View Source' shows the correct xml data loaded but nothing displayed.  Replacing the href with an internet link (href=\"http://207.5.45.208/other/shazam/olssamp.xsl\")
I can see via modem activity that this file was never accessed.

So I am stumped.   If you have any other suggestions I would be most grateful.  You are right in suggesting that the temp file method is inappropriate.  The need to have this load (appearing to scroll) as output comes through is important in keeping with the style of the current program.
Scrolling is simple however I am hoping that the xml will render as it is loaded (like a lengthy simple HTML page) with the right options.

Regards

David
0
 
RupreckAuthor Commented:
To add to this.  It seems that I can get some xml to display using:

// Load the default xml document
CString sAppName=AfxGetAppName();
CString sResourceID;
sResourceID.Format("%d", IDR_EMPTY_XML);
CString sNavigatePath;
sNavigatePath ="res://"+sAppName+".exe/"+sResourceID;
Navigate2(sNavigatePath);

Where the resource in this case is inserted as an HTML page containing XML.  ie

<?xml version="1.0" standalone="no"?>
<?xml-stylesheet type="text/xsl" href="file://c:\OLSSAMP.xsl"?>
<!-- Here begins the XML data -->
<OUTPUT>
  <METHOD ID="OLS">
    <COMMAND>OLS CONSUME INCOME PRICE / ANOVA PCOV</COMMAND>
  </METHOD>  
</OUTPUT>

I can now add text to the window using Dans method 3) above however it is treated as html again and the tags are ignored.

I have a feeling that having xml stream into IE and expecting it to render with the xsl sheet dynamically is impossible.  Microsoft probably haven't seen a need for this although HTML is rendered correctly with the right formatting.

David
0
Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
RupreckAuthor Commented:
To add to this.  It seems that I can get some xml to display using:

// Load the default xml document
CString sAppName=AfxGetAppName();
CString sResourceID;
sResourceID.Format("%d", IDR_EMPTY_XML);
CString sNavigatePath;
sNavigatePath ="res://"+sAppName+".exe/"+sResourceID;
Navigate2(sNavigatePath);

Where the resource in this case is inserted as an HTML page containing XML.  ie

<?xml version="1.0" standalone="no"?>
<?xml-stylesheet type="text/xsl" href="file://c:\OLSSAMP.xsl"?>
<!-- Here begins the XML data -->
<OUTPUT>
  <METHOD ID="OLS">
    <COMMAND>OLS CONSUME INCOME PRICE / ANOVA PCOV</COMMAND>
  </METHOD>  
</OUTPUT>

I can now add text to the window using Dans method 3) above however it is treated as html again and the tags are ignored.

I have a feeling that having xml stream into IE and expecting it to render with the xsl sheet dynamically is impossible.  Microsoft probably haven't seen a need for this although HTML is rendered correctly with the right formatting.

David
0
 
RupreckAuthor Commented:
No solution has been found to this.  Dans suggestion applied well to HTML however not to XML so that no answer to how to render an XML stream has been found.
0
 
DanRollinsCommented:
The key seems to be gettign the IDispatch* for the XMLDOMDocument.  Are you interested in followup?

-- Dan
0
 
RupreckAuthor Commented:
Actually I posted the question again as 'Rendering an XML Stream II' and the accepted answer was given as:

1) create 2 IXMLDOMDocument objects
2) set the async property on both to false
3) load 1 with the xml and the other with the xsl documents
4) BSTR bstrHTML=xmlDoc.transformNode(xslDoc);
5) insert the html into your browser (which you seem to know how to do)

I then did it in c++ and will post the code somewhere in time.

Thanks for the comment

David
0
 
Asta CuCommented:
Please update the expert here who have so willingly stepped in to help you, since much time has passed since your last comments, and Email notifications may not have been generated to the participating experts here due to some problems at that time.  If you've been helped, accept the respective question by that expert to grade and close it.

Somewhat off-topic, but important.

****************************** ALERT********************************
WindowsUpdate - Critical Update alert March 28, 2002 from Microsoft
http://www.microsoft.com/technet/treeview/default.asp?url=/technet/security/bulletin/ms02-015.asp
Synopsis:
Microsoft Security Bulletin MS02-015  
28 March 2002 Cumulative Patch for Internet Explorer
Originally posted: March 28, 2002
Summary
Who should read this bulletin: Customers using Microsoft® Internet Explorer
Impact of vulnerability: Two vulnerabilities, the most serious of which would allow script to run in the Local Computer Zone.
Maximum Severity Rating: Critical
Recommendation: Consumers using the affected version of IE should install the patch immediately.
Affected Software:
Microsoft Internet Explorer 5.01
Microsoft Internet Explorer 5.5
Microsoft Internet Explorer 6.0

Thought you'd appreciate knowing this.
":0)
Asta
0
 
RupreckAuthor Commented:
The answer for XML is in my later comments however these methods are the best way to get HTML into the browser; which is needed after the .TransformNode() method.
0
 
DanRollinsCommented:
Thanks Rupreck.  This is good information.  I appreciate your returning to finalize this Q.  -- Dan
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.