Solved

Rendering an XML stream

Posted on 2001-06-12
10
704 Views
Last Modified: 2013-11-20
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
0
Comment
Question by:Rupreck
  • 6
  • 3
10 Comments
 
LVL 49

Accepted Solution

by:
DanRollins earned 300 total points
ID: 6184075
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
 

Author Comment

by:Rupreck
ID: 6186715
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
 

Author Comment

by:Rupreck
ID: 6192275
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
 

Author Comment

by:Rupreck
ID: 6192676
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
 

Author Comment

by:Rupreck
ID: 6222591
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
Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

 
LVL 49

Expert Comment

by:DanRollins
ID: 6307221
The key seems to be gettign the IDispatch* for the XMLDOMDocument.  Are you interested in followup?

-- Dan
0
 

Author Comment

by:Rupreck
ID: 6321699
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
 
LVL 27

Expert Comment

by:Asta Cu
ID: 6907039
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
 

Author Comment

by:Rupreck
ID: 7137102
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
 
LVL 49

Expert Comment

by:DanRollins
ID: 7137196
Thanks Rupreck.  This is good information.  I appreciate your returning to finalize this Q.  -- Dan
0

Featured Post

How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
move a line in eclipse 3 60
jQuery or Javascript animation question 6 57
fix34  challenge 9 97
Annoying "thing" blocks my view 4 51
Exception Handling is in the core of any application that is able to dignify its name. In this article, I'll guide you through the process of writing a DRY (Don't Repeat Yourself) Exception Handling mechanism, using Aspect Oriented Programming.
JavaScript has plenty of pieces of code people often just copy/paste from somewhere but never quite fully understand. Self-Executing functions are just one good example that I'll try to demystify here.
Viewers will learn about arithmetic and Boolean expressions in Java and the logical operators used to create Boolean expressions. We will cover the symbols used for arithmetic expressions and define each logical operator and how to use them in Boole…
The viewer will learn the basics of jQuery, including how to invoke it on a web page. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery.: (CODE)

760 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now