Source: validateDOMsmart.cpp
The source code performs the following basic steps:
- Creates a DOM instance (
pXMLDoc
) to hold the XML data. - Creates a DOM instance (
pXSDDoc
) to hold the XML Schema definition. - Creates an
IXMLSchemaCollection
orIXMLSchemaCollection2
object (pSCache
). This object is also called a schema cache. The application then adds the XML Schema definition (pXSDDoc
) to thepSCache
. - Associates
pSCache
with theschemas
property of the DOM object for the XML data (pXMLDoc
). - Calls the following validation methods on the DOM object for XML data (
pXMLDoc
):- Calls the
validate
method onpXMLDoc
to validate the data set as a whole, and/or - Calls the
validateNode(pNode)
method onpXMLDoc
to validate a node object (pNode
) selected frompXMLDoc
.
- Calls the
Checks the error returned from validate
method and/or the validateNode(pNode)
method, to determine if the specified XML data set is valid against the given XML Schema definition.
C/C++ Source File (validateDOMsmart.cpp)
#include <stdio.h> #import <msxml5.dll> using namespace MSXML2; void dump_com_error(_com_error &e); int main(int argc, char* argv[]) { IXMLDOMDocument3Ptr pXMLDoc = NULL; IXMLDOMDocument3Ptr pXSDDoc = NULL; IXMLDOMParseErrorPtr pError = NULL; IXMLDOMSchemaCollectionPtr pSCache = NULL; IXMLDOMNodePtr pNode = NULL; IXMLDOMNodeListPtr pNodelist= NULL; HRESULT hr; CoInitialize(NULL); try{ // Load books.xml into a DOM instance. hr = pXMLDoc.CreateInstance(__uuidof(DOMDocument50)); if (FAILED(hr)) { printf( "Cannot create DOMDocument50 instance for XMLDoc\n"); return 0; } pXMLDoc->async = VARIANT_FALSE; pXMLDoc->validateOnParse = VARIANT_FALSE; if(pXMLDoc->load("books.xml") != VARIANT_TRUE) { printf( "Cannot load books.xml to XMLDoc object\n"); return 0; } // Load books.xsd into a DOM instance. hr = pXSDDoc.CreateInstance(__uuidof(DOMDocument50)); if (FAILED(hr)) { printf( "Cannot create DOMDocument50 instance for XSDDoc\n"); return 0; } pXSDDoc->async = VARIANT_FALSE; pXSDDoc->validateOnParse = VARIANT_FALSE; if(pXSDDoc->load("books.xsd") != VARIANT_TRUE) { printf( "Cannot load books.xsd to XSDDoc object\n"); return 0; } // Create a schema cache instance. hr = pSCache.CreateInstance(__uuidof(XMLSchemaCache50)); if (FAILED(hr)) { printf( "Cannot create XMLSchemaCache50 instance in pSCache\n"); return 0; } // Add the just-loaded schema definition to the schema collection. hr = pSCache->add("urn:books", pXSDDoc.GetInterfacePtr()); if (FAILED(hr)) { printf("Cannot add schema\n"); return 0; } // Associate the schema collection with the XMLDoc instance. pXMLDoc->schemas = pSCache.GetInterfacePtr(); // Validate the entire DOM. printf("Validating DOM...\n"); pError =pXMLDoc->validate(); if (pError->errorCode != 0) printf("\tXMLDoc is not valid because\n%s\n", (LPCSTR)pError->Getreason()); else printf("\tXMLDoc is validated: \n%s\n", (LPCSTR)pXMLDoc->xml); // Validate all //book nodes, node-by-node. pNodelist = pXMLDoc->selectNodes("//book"); printf("Validating all //book nodes, one by one ...\n"); for (int i=0; i<pNodelist->length; i++) { pNode = pNodelist->item[i]; pError = pXMLDoc->validateNode(pNode); if (pError->errorCode != 0) printf("\t<%s> (%d) is not valid because\n%s\n", (LPCSTR)pNode->nodeName, i, (LPCSTR)pError->Getreason()); else printf("\t<%s> (%d) is a valid node\n", (LPCSTR)pNode->nodeName, i); } // Validate all children of all book nodes, //book/*, node-by-node. pNodelist = pXMLDoc->selectNodes("//book/*"); printf("Validating all children of all book nodes, //book/*, one by one ...\n"); for (i=0; i<pNodelist->length; i++) { pNode = pNodelist->item[i]; pError = pXMLDoc->validateNode(pNode); if (pError->errorCode != 0) printf("\t<%s> (%d) is not valid because\n%s\n", (LPCSTR)pNode->nodeName, i, (LPCSTR)pError->Getreason()); else printf("\t<%s> (%d) is a valid node\n", (LPCSTR)pNode->nodeName, i); } } catch(_com_error &e) { dump_com_error(e); } pXMLDoc.Release(); pXSDDoc.Release(); pError.Release(); pSCache.Release(); pNode.Release(); pNodelist.Release(); CoUninitialize(); return 0; } void dump_com_error(_com_error &e) { printf("Error(dump_com_error)\n"); printf("\tCode = %08lx\n", e.Error()); printf("\tCode meaning = %s", e.ErrorMessage()); _bstr_t bstrSource(e.Source()); _bstr_t bstrDescription(e.Description()); printf("\tSource = %s\n", (LPCSTR) bstrSource); printf("\tDescription = %s\n", (LPCSTR) bstrDescription); }
To add the validateDOMsmart source code to the project
- Create a new C++ source file. For detailed instructions on how to do this, see Set Up My Visual C++ Project. Name the new file validateDOMsmart.cpp.
- Copy the C/C++ source code above, and paste it into the source file you just created.
Next, we'll add the resource files to the validateDOMsmart project.