Tim Cramer wrote:
David Bertoni wrote:
Tim Cramer wrote:
Hello everyone,
i have got a problem with the validation with a schema. I am using
the DOMBuilder, which has a DOMErrorHandler. When I try parsing a
invalid document, it is only parsed up to the wrong element, value,
etc without any error message / exception. How can I handle a schema
error? I set the features the following way:
DOMBuilder* probParser_ =
impl->createDOMBuilder(DOMImplementationLS::MODE_SYNCHRONOUS,0);
XNSQ DOMErrorHandler* errHandler = (DOMErrorHandler*) new XNSQ
HandlerBase();
This cast should not be necessary. Is there some reason it's there?
yes. I think I need a DOMErrorHandler for the DOMBuilder, but I cannot
have in instance of it, because it is abstract.
But if XNSQHandlerBase derives publically from DOMErrorHandler, then the
cast is unnecessary. If it doesn't, the cast is broken.
The reason DOMErrorHandler is abstract is because it's an interface that
you need to implement for the behavior you need.
probParser_->setErrorHandler(errHandler);
probParser_->setProperty(
XMLUni::fgXercesSchemaExternalNoNameSpaceSchemaLocation,
"file.xsd" );
probParser_->setFeature( XMLUni::fgDOMNamespaces, true);
probParser_->setFeature( XMLUni::fgXercesSchema, true);
probParser_->setFeature( XMLUni::fgXercesSchemaFullChecking, true);
What happens if you set this feature:
probParser_->setFeature( XMLUni::fgDOMValidateIfSchema, true);
The same effect.
you might also try:
probParser_->setValidationScheme(AbstractDOMParser::Val_Always);
I think this method is not defined for DOMBuilder.
try{
XNSQ DOMDocument* newProblem = probParser_->parse(sourceWrapper);
; }
catch(const XMLException& toCatch){
char* message = XNSQ XMLString::transcode(toCatch.getMessage());
std::cerr << "Parsing Error.XML Exception message is:\n"
<< message << "\nPlease check your Problemfile!\n";
XNSQ XMLString::release(&message);
return false;
}
catch(const DOMException& toCatch){
char* message = XNSQ XMLString::transcode(toCatch.msg);
std::cerr << "Parsing Error. DOM Exception message is:\n"
<< message << std::endl;
XNSQ XMLString::release(&message); }
catch(const SAXException& toCatch){
std::cerr << "error\n";
}
catch(...){
;//...
}
I hope your error handler is actually throwing the exceptions it
receives. Otherwise, they will just be swallowed. Since you didn't
provide any source code for your ErrorHandler, we can only guess.
I do not have my own error handler (HandlerBase is xerces class). I
thought the DOMBuilder::parse () would through an exception if the xml
data is not conform with the schema, wouldn't it?
Ahh, I thought your class was named XNSQHandlerBase, and my email client
was wrapping it. If you look at the code for HandlerBase, you'll see it
does absolutely nothing. You'll also see that it derives from the SAX base
class ErrorHandler, not DOMErrorHandler, so your prior cast is broken. Why
do you think forcing one class type to another is the solution for a
compilation error?
The standard behavior for the parser is to continue after a validation
error, for situations where all the validation errors should be reported.
If you want parsing to stop at the first error, you need to implement that
behavior.
Another test i have made is the following:
#define XNSQ XERCES_CPP_NAMESPACE_QUALIFIER
class XMLErrorHandler : public XNSQ DefaultHandler{
public:
void warning(const XNSQ SAXParseException& e){
std::cerr<< "+WARNING+\n";
}
void error(const XNSQ SAXParseException& e){
std::cerr<< "+ERROR+\n";
char* message = XNSQ XMLString::transcode(e.getMessage());
throw std::runtime_error( message );
XNSQ XMLString::release(&message);
}
void fatalError(const XNSQ SAXParseException& e){
error(e);
} };
But this does not solve the problem of the typecast:
XMLErrorHandler* errHandler = new XMLErrorHandler;
probParser_->setErrorHandler((XNSQ DOMErrorHandler*)( errHandler ) );
So what is the way to do it?
You don't do it. You derive your class from DOMErrorHandler and implement
what you need. Which in your case is throwing an exception to stop
parsing, or return false from DOMErrorHandler::handleError(), like the
documentation states.
Dave