Xerces C++: no error for non-existent file
I'm using the Xerces C++ DOM parser to read some XML files in a Visual C++ project. I have a class with a parse()
method that is supposed to read and validate my XML source file. This is what the method looks like:
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/dom/DOM.hpp>
#include <xercesc/parsers/XercesDOMParser.hpp>
#include <xercesc/framework/LocalFileInputSource.hpp>
using namespace std;
XERCES_CPP_NAMESPACE_USE
unsigned long RulesParser::parse( const wstring &xmlFile )
{
if( parserInitialized_ == false ) {
try {
XMLPlatformUtils::Initialize(); /* initialize xerces */
} catch( XMLException const &e ) {
return Status::PARSER_INIT_FAIL;
}
}
parserInitialized_ = true; /* indicate xerces has been
successfully initialized */
if( pDOMParser_ != NULL ) {
delete pDOMParser_;
}
pDOMParser_ = new XercesDOMParser; /* create a DOM parser instance */
/* set xerces options */
pDOMParser_->setDoNamespaces( true ); /* enable namespace processing */
pDOMParser_->setDoSchema( true ); /* enable schema processing */
pDOMParser_->setValidationScheme( XercesDOMParser::Val_Always ); /* parser always validates 开发者_JAVA技巧*/
pDOMParser_->setValidationSchemaFullChecking( true ); /* enable full schema checking */
auto_ptr< LocalFileInputSource > srcFile; /* XML source file loader */
try {
srcFile.reset( new LocalFileInputSource( xmlFile.c_str() ) );
} catch( const XMLException &e ) {
return Status::XML_SOURCE_LOAD_ERROR;
}
/* parse the file */
try {
pDOMParser_->parse( *srcFile );
} catch( const XMLException &e ) {
return Status::XML_SOURCE_PARSE_ERROR;
} catch( const DOMException &e ) {
return Status::XML_SOURCE_PARSE_DOM_ERROR;
}
return Status::OK;
}
The documentation for LocalFileInputSource
says the constructor will throw an XMLException
if the path doesn't resolve to a file. However, I can call this method with any arbitrary string and it executes to the end without any exceptions being raised. What am I doing wrong?
Also, the documentation for XercesDOMParser::parse()
says a SAXException
is one of the types of exceptions that it can throw. I find this confusing because from what I understand DOM and SAX parsers are 2 different animals, so why would the DOM parser throw a SAX exception?
See ErrorHandler
documentation.
You must declare and define a class that inherits from ErrorHandler
and implements its virtual methods (or you can extend the HandlerBase
class).
Then you must call setErrorHandler
on your parser instance passing an instance of your error handler, i.e. pDOMParser_->setErrorHandler(your_handler_instance)
.
Example usage from Xerces-C++ trunk samples: rows 231-233 of SAXPrint.cpp.
Update: example of custom error handler below.
#include <iostream>
#include <xercesc/sax/HandlerBase.hpp>
XERCES_CPP_NAMESPACE_USE
class CustomErrorHandler : public HandlerBase
{
public:
CustomErrorHandler() {}
void error(const SAXParseException& e)
{
handler(e);
}
void fatalError(const SAXParseException& e)
{
handler(e);
}
void warning(const SAXParseException& e)
{
handler(e);
}
private:
void handler(const SAXParseException& e)
{
char* message = XMLString::transcode(e.getMessage());
cerr << "line " << e.getLineNumber()
<< ", column " << e.getColumnNumber()
<< " -> " << message << "\n\n";
XMLString::release(&message);
}
};
I don't think that the documentation says what you think it does, it says it will; throw:
XMLException If the path is relative and doesn't properly resolve to a file.
Your task, should you choose to accept it, is to find out what "relative" means. I'm afraid I I haven't used Xerces for years (though it is quite competent) - I prefer to use small, simple SAX parsers to build my own models rather than use a DOM, and can't remember how the filename stuff works.
And I think that the reason that you might get SAX exceptions is that Xerces uses SAX to build its DOM.
The 2.8 Doc (you have linked) says,
XMLException If the path is relative and doesn't properly resolve to a file
are you actually using a relative path?
maybe this used to be the case for some platform specific cases, but I can't see where this is raised in Xercese 2.7 (code I happen to have).
Looking at LocalFileFormatTarget it can throw an exception for 'CouldNotOpenFile', but it isn't documented as raising an exception.
What version of xerces are you using?
Opening the file for reading/parsing looks like it might raise an exception for the missing file of type 'CouldNotReadFromFile'. But that could be caught up with the error handling as Vanni is talking about.
I know this is old, but yes indeed I found that XercesDOMParser
throws a SAXParseException
if the file is not found. No custom error handler needed, just catch that exception.
精彩评论