You are viewing a plain text version of this content. The canonical link for it is here.
Posted to c-users@xerces.apache.org by Tim Cramer <ti...@iem.rwth-aachen.de> on 2007/04/11 18:36:37 UTC

validation with DOMBuilder

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();
       probParser_->setErrorHandler(errHandler);


   probParser_->setProperty( 
XMLUni::fgXercesSchemaExternalNoNameSpaceSchemaLocation,
                        "file.xsd" );
     probParser_->setFeature( XMLUni::fgDOMNamespaces, true);
   probParser_->setFeature( XMLUni::fgXercesSchema, true);
   probParser_->setFeature( XMLUni::fgXercesSchemaFullChecking, true);


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(...){
    ;//...
 }


Thanks for your help.

Tim


Re: validation with DOMBuilder

Posted by Tim Cramer <ti...@iem.rwth-aachen.de>.
Tim Cramer wrote:
>
> 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?
>
> Another test i have made is the following:
>
> [stupid sourccode]
>
> So what is the way to do it?
> Or is it possible that schema support is not implemented for the 
> DOMBuilder (DOM Level 3) yet (the canSetFeature() methods return TRUE, 
> so it might be implemented...)? Thanks a lot for your help.
>
>
> Tim

Ok. I think i have solved my problem. What I needed was a class like this:

    class XMLErrorHandler : public XNSQ DOMErrorHandler

And than overload:
     bool handleError(const XNSQ DOMError& error){

Tim


Re: validation with DOMBuilder

Posted by David Bertoni <db...@apache.org>.
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

Re: validation with DOMBuilder

Posted by Tim Cramer <ti...@iem.rwth-aachen.de>.
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.
>
>>       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?

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?
Or is it possible that schema support is not implemented for the 
DOMBuilder (DOM Level 3) yet (the canSetFeature() methods return TRUE, 
so it might be implemented...)? Thanks a lot for your help.


Tim


Re: validation with DOMBuilder

Posted by David Bertoni <db...@apache.org>.
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?

>       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);

you might also try:

      probParser_->setValidationScheme(AbstractDOMParser::Val_Always);

> 
> 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.

Dave

Re: validation with DOMBuilder

Posted by Boris Kolpackov <bo...@codesynthesis.com>.
Hi Tim,

Tim Cramer <ti...@iem.rwth-aachen.de> writes:

> When I try parsing a invalid document, it is only parsed up to the
> wrong element, value, etc without any error message / exception.

That would normally indicate there is something wrong with your error
handler.


>      XNSQ DOMErrorHandler* errHandler = (DOMErrorHandler*) new XNSQ
> HandlerBase();
>        probParser_->setErrorHandler(errHandler);

What does HandlerBase look like?


hth,
-boris
-- 
Boris Kolpackov
Code Synthesis Tools CC
http://www.codesynthesis.com
Open-Source, Cross-Platform C++ XML Data Binding