Source: validateDOMsmart.cpp
[This sample code uses features that were first implemented in MSXML 5.0 for Microsoft Office Applications.]
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/orCalls the
validateNode(pNode)
method onpXMLDoc
to validate a node object (pNode
) selected frompXMLDoc
.
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>
#include <tchar.h>
#import <msxml6.dll>
// Macro that calls a COM method returning HRESULT value.
#define CHK_HR(stmt) do{ hr=(stmt); if (FAILED(hr)) goto CleanUp; } while(0)
void dump_com_error(_com_error &e)
{
_bstr_t bstrSource(e.Source());
_bstr_t bstrDescription(e.Description());
printf("Error(dump_com_error)\n");
printf("\tCode = %08lx\n", e.Error());
printf("\tCode meaning = %s", e.ErrorMessage());
printf("\tSource = %s\n", (LPCSTR) bstrSource);
printf("\tDescription = %s\n", (LPCSTR) bstrDescription);
}
void validateDOMsmart()
{
MSXML2::IXMLDOMDocument3Ptr pXMLDoc;
MSXML2::IXMLDOMDocument2Ptr pXSDDoc;
MSXML2::IXMLDOMParseErrorPtr pError;
MSXML2::IXMLDOMSchemaCollectionPtr pSCache;
MSXML2::IXMLDOMNodePtr pNode;
MSXML2::IXMLDOMNodeListPtr pNodelist;
HRESULT hr = S_OK;
try
{
// Load books.xml into a DOM instance.
CHK_HR(pXMLDoc.CreateInstance(__uuidof(MSXML2::DOMDocument60), NULL, CLSCTX_INPROC_SERVER));
pXMLDoc->async = VARIANT_FALSE;
pXMLDoc->validateOnParse = VARIANT_FALSE;
if(pXMLDoc->load(L"books.xml") != VARIANT_TRUE)
{
printf("Cannot load books.xml to DOMDocument object.\n");
CHK_HR(pXMLDoc->parseError->errorCode);
}
// Load books.xsd into a DOM instance.
CHK_HR(pXSDDoc.CreateInstance(__uuidof(MSXML2::DOMDocument60), NULL, CLSCTX_INPROC_SERVER));
pXSDDoc->async = VARIANT_FALSE;
pXSDDoc->validateOnParse = VARIANT_FALSE;
if(pXSDDoc->load(L"books.xsd") != VARIANT_TRUE)
{
printf("Cannot load books.xsd to DOMDocument object.\n");
CHK_HR(pXSDDoc->parseError->errorCode);
}
// Create a schema cache instance.
CHK_HR(pSCache.CreateInstance(__uuidof(MSXML2::XMLSchemaCache60), NULL, CLSCTX_INPROC_SERVER));
// Add the just-loaded schema definition to the schema collection.
CHK_HR(pSCache->add(L"urn:books", pXSDDoc.GetInterfacePtr()));
// 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(L"//book");
printf("Validating all //book nodes, one by one ...\n");
for (long 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(L"//book/*");
printf("Validating all children of all book nodes, //book/*, one by one ...\n");
for (long 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);
}
CleanUp:
return;
}
int _tmain(int argc, _TCHAR* argv[])
{
HRESULT hr = CoInitialize(NULL);
if (SUCCEEDED(hr))
{
validateDOMsmart();
CoUninitialize();
}
return 0;
}
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.