Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
[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
IXMLSchemaCollectionorIXMLSchemaCollection2object (pSCache). This object is also called a schema cache. The application then adds the XML Schema definition (pXSDDoc) to thepSCache.Associates
pSCachewith theschemasproperty of the DOM object for the XML data (pXMLDoc).Calls the following validation methods on the DOM object for XML data (
pXMLDoc):Calls the
validatemethod onpXMLDocto validate the data set as a whole, and/orCalls the
validateNode(pNode)method onpXMLDocto 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.