Bali can produce C++ source code targeted to the Win32/Visual C++ environment. The generated code can validate MSXML DOM tree or MSXML SAX events.
To compile myschema.rng
into a validatelet in the foo
namespace to the src
folder, type in as follows:
$ java -jar bali.jar myschema.rng -ow src foo bar
The third parameter of the "-ow" option specifies the stem of the factory method names.
This will generate bar.h
and bar.cpp
into the src
folder, along with other source/header files necessary to run a validatelet.
First, you need to modify stdafx.h
and have it include a couple of header files necessary for a validatelet.
**********************************
Generated bar.h
defines methods that create a validatelet. Your application should include this header file and call these methods to obtain an instance of the validatelet.
To create a validatelet for MSXML DOM, call the createBarDOMValidatelet()
method as follows:
bali::IValidatelet* pValidatelet = foo::createBarDOMValidatelet();
The IValidatelet
interface defines one method that takes a MSXML DOM document or element and validate it. If you pass a document, this method will validate the whole document. If you pass an element, it will validate a sub-tree rooted at that element.
Upon the completion, this method returns true if the validation was successful, and false otherwise. You can also receive a pointer to the node that causes a failure (see the header file for the detail.)
Thus the code will look like:
// load a document IXMLDOMDocumentPtr pDOMDocument(__uuidof(DOMDocument)); pDOMDocument->async = false; pDOMDocument->load(myXml); if( pValidatelet->validate( pDOMDocument ) ) { // this document is OK. The show will go on } else { // abort. there was an error. }
The same validatelet object can be reused many times, as long as it is used by only one thread at any given time.
Once you finish using it, it is your resonsibility to delete a validatelet.
delete pValidatelet;
Another method defined in the header file is the createBarSAXValidatelet
method. This method will return a ISAXContentHandler
interface that implements a validatelet. This interface will allow you to validate SAX events.
MSXML2::ISAXContentHandler* pValidatelet = foo::createBarSAXValidatelet();
You can then use this handler to validate SAX events. Every time the startDocument callback is called, a validatelet re-initializes itself. Thus you can reuse one SAX validatelet as many times as you want.
Since SAX validatelet is a COM object, you need to release it explicitly.
pValidatelet->Release();
Although it was my favorite platform until a year or two ago, I no longer work on the Win32 platform. Therefore, it is very likely that the interface I provided here is somewhat different from what it should be.
I solicit any comment regarding how a validatelet should be exposed to the client application.