[ Home | Syllabus | Course Notes | Assignments | Search]
This program is like the ones I used to teach in this course - its uses the COM (Component Object Model) developed my microsoft and it lacks many of the functions available in the FCL that make XML processing so much easier.
It makes you appreciate how much better a toolkit .NET provides
#include <stdio.h> #include <windows.h> void ShowGuitarType (IXMLDOMNode* pNode); BOOL GetChildElementByTagName (LPOLESTR pName, IXMLDOMNode* pParent, IXMLDOMNode** ppNode); BOOL IsElementNamed (LPOLESTR pName, IXMLDOMNode* pNode); int main (int argc, char* argv[]) { HRESULT hr = CoInitialize (NULL); // Instantiate the MS XML parser IXMLDOMDocument* pDoc; hr = CoCreateInstance (CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, IID_IXMLDOMDocument, (void**) &pDoc); if (SUCCEEDED (hr)) { // Load Guitars.xml VARIANT_BOOL success; BSTR file = SysAllocString (OLESTR ("Guitars.xml")); VARIANT var; var.vt = VT_BSTR; var.bstrVal = file; pDoc->put_async (VARIANT_FALSE); hr = pDoc->load (var, &success); SysFreeString (file); if (SUCCEEDED (hr) && hr != S_FALSE) { // Get a list of elements named "Guitar" IXMLDOMNodeList* pNodeList; BSTR tag = SysAllocString (OLESTR ("Guitar")); hr = pDoc->getElementsByTagName (tag, &pNodeList); SysFreeString (tag); if (SUCCEEDED (hr)) { // Get a count of the elements returned long count; hr = pNodeList->get_length (&count); if (SUCCEEDED (hr)) { pNodeList->reset (); // Walk the list element by element for (int i=0; i<count; i++) { IXMLDOMNode* pNode; hr = pNodeList->get_item (i, &pNode); if (SUCCEEDED (hr)) { // Show the Make and Model subelements ShowGuitarType (pNode); pNode->Release (); } } } pNodeList->Release (); } } pDoc->Release (); } CoUninitialize (); return 0; } void ShowGuitarType (IXMLDOMNode* pNode) { IXMLDOMNode* pMakeNode; IXMLDOMNode* pModelNode; // Get an IXMLDOMNode pointer to the Make subelement if (GetChildElementByTagName (OLESTR ("Make"), pNode, &pMakeNode)) { // Get the Make subelement's text BSTR make; HRESULT hr = pMakeNode->get_text (&make); if (SUCCEEDED (hr) && hr != S_FALSE) { // Get an IXMLDOMNode pointer to the Model subelement if (GetChildElementByTagName (OLESTR ("Model"), pNode, &pModelNode)) { // Get the Model subelement's text BSTR model; hr = pModelNode->get_text (&model); if (SUCCEEDED (hr) && hr != S_FALSE) { // Output the guitar's make and model wprintf (OLESTR ("%s %s\n"), make, model); SysFreeString (model); } pModelNode->Release (); } SysFreeString (make); } pMakeNode->Release (); } } BOOL GetChildElementByTagName (LPOLESTR pName, IXMLDOMNode* pParent, IXMLDOMNode** ppNode) { // Get a list of nodes that are children of pParent IXMLDOMNodeList* pNodeList; HRESULT hr = pParent->get_childNodes (&pNodeList); if (SUCCEEDED (hr)) { // Get a count of the nodes returned long count; hr = pNodeList->get_length (&count); if (SUCCEEDED (hr)) { pNodeList->reset (); // Walk the list node by node for (int i=0; i<count; i++) { IXMLDOMNode* pNode; hr = pNodeList->get_item (i, &pNode); if (SUCCEEDED (hr)) { // If the node is an element whose name matches // the input name, return an IXMLDOMNode pointer if (IsElementNamed (pName, pNode)) { *ppNode = pNode; pNodeList->Release (); return TRUE; } pNode->Release (); } } } pNodeList->Release (); } return FALSE; } BOOL IsElementNamed (LPOLESTR pName, IXMLDOMNode* pNode) { BOOL retval; // Get the node type DOMNodeType type; HRESULT hr = pNode->get_nodeType (&type); if (SUCCEEDED (hr) && type == NODE_ELEMENT) { // If the node is an element, get its name BSTR name; hr = pNode->get_nodeName (&name); if (SUCCEEDED (hr)) { // If the element name matches the input name, return // TRUE to indicate a match retval = (wcscmp (name, pName) == 0) ? TRUE : FALSE; SysFreeString (name); } } return retval; }
F1: interface to a COM object
F2: Compatible types with visual basic, long pointer(32 bit) to a Object Linking and Embedding (OLE) string
F3: returns the v-table of a polymorphic object (ie. a pointer to an array of pointers to function addresses)
F4 Gets the COM system initialized
Here is the equivalent program in C#
using System; using System.Xml; class MyApp { static void Main () { XmlDocument doc = new XmlDocument (); doc.Load ("Guitars.xml"); XmlNodeList nodes = doc.GetElementsByTagName ("Guitar"); foreach (XmlNode node in nodes) { Console.WriteLine ("{0} {1}", node["Make"].InnerText, node["Model"].InnerText); } } }