Microsoft KB Archive/246230

= SAMPLE: XMLTree Uses XML DOM from C++ =

Article ID: 246230

Article Last Modified on 8/5/2004

-

APPLIES TO


 * Microsoft Internet Explorer 5.0
 * Microsoft Internet Explorer 5.01
 * Microsoft Internet Explorer 5.5
 * Microsoft XML Parser 2.5
 * Microsoft XML Parser 2.6
 * Microsoft XML Core Services 4.0
 * Microsoft XML Core Services 4.0
 * Microsoft Visual C++ 6.0 Service Pack 5

-



This article was previously published under Q246230



SUMMARY
XMLTree.exe is a sample that demonstrates how to use the MSXML XML DOM interfaces from a C++ application.

XMLTree loads XML documents from a URL and graphically displays them in a tree view. It allows manipulation of the XML data on a node-by-node basis and supports saving the data out to a file on the local disk.



MORE INFORMATION
The following file is available for download from the Microsoft Download Center:

http://download.microsoft.com/download/ie55/demo1/1.0/WIN98Me/EN-US/XMLTree.exe

Release Date: Jul-21-2000

For additional information about how to download Microsoft Support files, click the following article number to view the article in the Microsoft Knowledge Base:

119591 How to Obtain Microsoft Support Files from Online Services

Microsoft scanned this file for viruses. Microsoft used the most current virus-detection software that was available on the date that the file was posted. The file is stored on security-enhanced servers that help to prevent any unauthorized changes to the file.

To use XMLTree, first select an XML file to parse and display by typing a file path and then clicking Open URL. To assist in selecting the correct file, there is a Browse button that brings up a Windows Explorer File dialog box. You can choose the form of load, either synchronous or asynchronous, by selecting or clearing the Async button. This is purely for development demonstration purposes because both forms of load are functionally equivalent to the user of this sample.

If the XML file is opened successfully, the file is displayed in tree format in the main window of the dialog box. The Refresh button directs the application to reread the object model of the document into the tree, because some changes and move operations don't immediately show correctly in the Tree View window.

Users can manipulate the tree contents by right-clicking on a node in the tree. This brings up a context menu that enables the user to add and remove node elements, as well as replace node contents with the data in the name and value text boxes at the bottom of the XMLTree dialog box. Once the user is finished making edits, the user can save the XML node data back to any file name by using the Save To File button.

XMLTree demonstrates the following basic tasks:
 * Load XML documents synchronously or asynchronously.

OnOpenURL handles the two main cases for loads in XMLTree, synchronous or asynchronous, as chosen through the async button in the dialog box.

Synchronous loading is self-explanatory. Asynchronous loading requires that XMLTree sink the onreadystate event on MSXML. The document object model is not ready for reading or modification until this event has fired and the readystate property of the document is "4" (complete).
 * Sink events on MSXML from C++ through Active Template Library (ATL) event sinks.

You can best accomplish event sinking by using ATL's AtlAdvise method and an ATL class that uses IDispEvent(Simple)Impl. The sample's XMLDOMDocumentEventsSink class uses IDispEventSimpleImpl as demonstrated in the ATL sample. This class uses IDispEventSimpleImpl as is described in the ATL documentation and demonstrated in the ATL sample "ATLEventHandling".

To communicate the event's reception from the event sink object to the XMLTree dialog object, CXMLDOMDocumentEventSink posts private Window messages to the dialog object. This allows the event to return before the dialog does the lengthy process of the Refresh.
 * Save the current XML object model to a file.

This sample first uses a CFileDialog to request the file name from the user and then calls IXMLDOMDocument::save with the filename.
 * Display the object model of an XML document in tree view format.

This feature is obviously the critical part of this application, with FillXMLTree as the main implementation method, begun by OnRefresh in most circumstances.

FillXMLTree uses a number of helper functions. Its flow is relatively simple: a recursive depth-first traversal of XML DOM nodes and their children.

The NodeToTextImage method is used to determine the text and icon displayed for each node.

AddNodeToTree does the actual TreeView control insert.
 * Create new elements, attributes, CDATA, comments, or text in the XML object model.

All of the OnTreePopup*** methods affect the addition and removal of items in the tree. The centerpiece of these methods uses one of the IXMLDOMDOcument::Create*** methods, such as CreateElement, to create the node and then appendChild that node under the currently selected node.
 * Change names and values of various nodes in the XML tree.

OnTreePopupChange handles this operation, which seems to be strangely more complicated than it should be. Unfortunately, the methods and properties for manipulating node contents are not completely orthogonal across the different types of nodes. Certain nodes don't allow for the modification of the "name" property" and others don't have a "value" property. Even worse, attributes are stored in the tree in a way that is completely different from other node types and requires the use of the IXMLDOMNamedNodeMap interface to manipulate them.
 * Cut and paste nodes as text and Unicode text.

OnTreePopupCopy, of course, contains the majority of the code for putting XML nodes onto the clipboard as text and unicode text. This is actually very simple thanks to the xml property of IXMLDOMNode, which does all the laborious work of translating the XML node and all its children into a handy string. XMLTree then uses COleDataSource to package this up in two different clipformats. (See the documentation for COleDataSource for more information about the use of this standard Microsoft Foundation Classes [MFC] class.)

For cut operations, OnTreePopupCopy is used first to copy the nodes, and then OnTreePopupDelete is used to delete the nodes.
 * Cut and paste nodes inside XMLTree as XML nodes.

XML nodes are only copied inside the XMLTree application and are never really added to the clipboard. This is accomplished with a single global variable, g_pClipboardNode. To keep the clipboard behavior consistent, however, XMLTREE must have a way of determining when the XML node on the clipboard has been replaced by a cut/copy in another application. To this end, XMLTREE stores a dummy HGLOBAL on the clipboard with a third, custom clipformat. This clipformat is checked by the paste operation.

A possible future modification is to use this dummy clipformat to store an actual XML node and allow XML node data to be cut and pasted across process boundaries.

The majority of the code is in one class, the dialog class CXmltreeDlg. Unless otherwise noted, any code discussed in this section is in the C++ implementation file for that class, XMLTreeDLG.CPP.

NOTE: The XMLTree sample uses Microsoft Visual C++ COM compiler support heavily, including Visual C++ smart pointers, COM compiler exceptions, and extension classes, such as _bstr_t. Developers who are not familiar with this syntax should familiarize themselves with the documentation available at the following Microsoft Web site:

http://msdn.microsoft.com/library/default.asp?URL=/library/devprods/vs6/visualc/vccore/_core_compiler_com_support.3a_.overview.htm

Visual C++ Documentation: Using Visual C++; Adding Program Functionality; Overviews; Compiler COM Support: Overview

NOTE: The sample code provided in this article contains a reference to MSXML 2.5 or earlier. If a newer version of MSXML has been installed in replace mode on your machine, the sample code will automatically use this new version. If a newer version of MSXML has been installed in side-by-side mode on your machine, the code may use the older version. If a newer version of MSXML has been installed in side-by-side mode, you must explicitly use the Globally Unique Identifiers (GUIDs) or ProgIDs for that version to run the sample code. For example, MSXML version 4.0 can only be installed in side-by-side mode. For additional information about the code changes that are required to run the sample code with the MSXML 4.0 parser, click the following article number to view the article in the Microsoft Knowledge Base:

305019 INFO: MSXML 4.0 Specific GUIDs and ProgIds

