Q246230 - SAMPLE: XMLTree Uses XML DOM from C++
-------------------------------------------------------------------------------
The information in this article applies to:
- Microsoft Internet Explorer (Programming) versions 5, 5.01, 5.5
-------------------------------------------------------------------------------
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.
Click the file name below to download the file:
XMLTree.exe (Download Center URL /XMLTree.exe)
Release Date: Mar-17-1999
For more information about how to download files from the Microsoft Download
Center, please visit the Download Center at the following Web address
http://www.microsoft.com/downloads/search.asp
and then click "How to use the Microsoft Download Center".
Microsoft used the most current virus detection software available on the date of
posting to scan this file for viruses. Once posted, the file is housed on secure
servers that 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 Progra