c++xmlxsdxercesxerces-c

xml file validation with in-memory schema in xerces c++


#include <xercesc/framework/Wrapper4InputSource.hpp>
#include <xercesc/util/XMLString.hpp>
#include <xercesc/sax2/SAX2XMLReader.hpp>
#include <xercesc/parsers/XercesDOMParser.hpp>
#include <xercesc/dom/DOMLSParser.hpp>
#include <xercesc/dom/DOMImplementation.hpp>
#include <xercesc/sax2/XMLReaderFactory.hpp>
#include <xercesc/framework/MemBufInputSource.hpp>
#include <xercesc/framework/LocalFileInputSource.hpp>
#include <xercesc/sax/ErrorHandler.hpp>
#include <xercesc/sax/SAXParseException.hpp>
#include <xercesc/sax/Parser.hpp>
#include <xercesc/validators/common/Grammar.hpp>

class CErrorHandler : public xercesc::DefaultHandler 
{
public:    
CErrorHandler();

virtual ~CErrorHandler();

void startElement(const   XMLCh* const    uri,
                  const   XMLCh* const    localname,
                  const   XMLCh* const    qname,
                  const   XERCES_CPP_NAMESPACE::Attributes&     attrs
);

void endElement(const   XMLCh* const    uri,
                const   XMLCh* const    localname,
                const   XMLCh* const    qname
);

void characters(const   XMLCh* const    chars,
                const   XMLSize_t       length
);

void fatalError(const xercesc::SAXParseException&);
};

   CErrorHandler::CErrorHandler()
   {
   }

   CErrorHandler::~CErrorHandler()
   {
   }

   void CErrorHandler::startElement(const   XMLCh* const    uri,
                                    const   XMLCh* const    localname,
                                    const   XMLCh* const    qname,
                                    const   xercesc::Attributes&     attrs)
   {
      char* name = xercesc::XMLString::transcode(localname);
      std::cout << name;
      xercesc::XMLString::release(&name);
   }

   void CErrorHandler::endElement(const   XMLCh* const    uri,
                                  const   XMLCh* const    localname,
                                  const   XMLCh* const    qname)
   {
      char* name = xercesc::XMLString::transcode(localname);
      xercesc::XMLString::release(&name);
   }

   void CErrorHandler::fatalError(const xercesc::SAXParseException& exception)
   {
      char* message = xercesc::XMLString::transcode(exception.getMessage());
      std::cout << "Error: " << message << " at line: " << exception.getLineNumber() << std::endl;
      xercesc::XMLString::release(&message);
   }

   void CErrorHandler::characters(const   XMLCh* const    chars,
                                  const   XMLSize_t       length
   )
   {
   }

bool validateSchema()
{

std::string XSD_SHEMA ="<?xml version=\"1.0\" encoding=\"UTF-8\" ?>...";   

try 
   {
      xercesc::XMLPlatformUtils::Initialize();
   }

   catch (const  XERCES_CPP_NAMESPACE::XMLException& toCatch) 
   {
      char* message =  xercesc::XMLString::transcode(toCatch.getMessage());
      std::cout << "Error during initialization!" << std::endl;
      std::cout << "Exception message is: " << message;
      XERCES_CPP_NAMESPACE::XMLString::release(&message);
      return false;
   }

   xercesc::SAX2XMLReader* parser =  xercesc::XMLReaderFactory::createXMLReader();
   parser->setFeature( xercesc::XMLUni::fgSAX2CoreValidation, true);
   parser->setFeature( xercesc::XMLUni::fgSAX2CoreNameSpaces, true);

   xercesc::DefaultHandler* defaultHandler = new CErrorHandler();
   xercesc::ContentHandler* h  = new CErrorHandler();

   xercesc::MemBufInputSource mis(reinterpret_cast< const XMLByte* >(XSD_SHEMA.c_str() ), XSD_SHEMA.size (), "/schema.xsd");
   xercesc::Wrapper4InputSource wmis (&mis, false);

   parser->loadGrammar (&wmis, xercesc::Grammar::SchemaGrammarType, true);
   parser->setFeature (xercesc::XMLUni::fgXercesUseCachedGrammarInParse, true);

   void* id = (void*)("file:///schema.xsd");
   parser->setProperty (xercesc::XMLUni::fgXercesSchemaExternalNoNameSpaceSchemaLocation, id);

   parser->setContentHandler(h);
   parser->setErrorHandler(defaultHandler);

   try 
   {
      parser->parse(mXMLFilePath.c_str());
   }

   catch (const  xercesc::XMLException& toCatch) 
   {
      char* message =  xercesc::XMLString::transcode(toCatch.getMessage());
      std::cout << "Exception message is: "<< message << std::endl;;
      xercesc::XMLString::release(&message);
      return false;
   }

   catch (const  xercesc::SAXParseException& toCatch) 
   {
      char* message =  xercesc::XMLString::transcode(toCatch.getMessage());
      std::cout << "Exception message is: " << message << std::endl;;
      xercesc::XMLString::release(&message);
      return false;
   }

   catch (...) 
   {
      std::cout << "Unexpected Exception" ;
      return false;
   }

   delete parser;
   delete defaultHandler;
   return true;
}

I am trying to validate xml file with path mXMLFilePath and xsd schema in string XSD_SHEMA in c++ with Xerces lib. I created CErrorHandler class and initialized it, set schema nolocation parameter for not setting in xml path to schema. It build`s, but not work. Have somebody any ideas?


Solution

  • #include <xercesc/sax2/SAX2XMLReader.hpp>
    #include <xercesc/sax2/XMLReaderFactory.hpp>
    #include <xercesc/sax/ErrorHandler.hpp>
    #include <xercesc/sax/SAXParseException.hpp>
    
    #include <xercesc/validators/common/Grammar.hpp>
    #include <xercesc/parsers/SAXParser.hpp>
    #include <xercesc/framework/MemBufInputSource.hpp>
    #include <xercesc/util/XMLString.hpp>
    
    #include <string>
    #include <iostream>
    
    class CErrorHandler : public xercesc::ErrorHandler 
    {
    public:
       /** Warning message method */
       void warning(const xercesc::SAXParseException& ex);
       /** Error message method */
       void error(const xercesc::SAXParseException& ex);
       /** Fatal error message method */
       void fatalError(const xercesc::SAXParseException& ex);
       /** Errors resetter method */
       void resetErrors();
    private:
       /** Based message reporter method */
       void reportParseException(const xercesc::SAXParseException& ex);
    };
    void CErrorHandler::reportParseException(const xercesc::SAXParseException& ex)
    {
       char* message = xercesc::XMLString::transcode(ex.getMessage());
       std::cout << message << " at line " << ex.getLineNumber() << " column " << ex.getColumnNumber() << std::endl;
    
       xercesc::XMLString::release(&message);
    }
    
    void CErrorHandler::warning(const xercesc::SAXParseException& ex)
    {
       reportParseException(ex);
    }
    
    void CErrorHandler::error(const xercesc::SAXParseException& ex)
    {
       reportParseException(ex);
    }
    
    void CErrorHandler::fatalError(const xercesc::SAXParseException& ex)
    {
       reportParseException(ex);
    }
    
    void CErrorHandler::resetErrors()
    {
    }
    
    
    
    class CXmlValidator
    {
    public:
       /** Constructor method */
       CXmlValidator();
       /** Xml file setter method */
       void setFilePath(const std::string &filePath);
       /** Destructor method */
       ~CXmlValidator();
       /** Xml file with schema validation method */
       bool validateSchema();
    private:
       /** Xml file */
       std::string mXMLFilePath;
    };
    
    
    CXmlValidator::CXmlValidator():
       mXMLFilePath("")
    {
    }
    
    CXmlValidator::~CXmlValidator()
    {
    }
    
    void CXmlValidator::setFilePath(const std::string &filePath)
    {
       mXMLFilePath = filePath;
    }
    
    bool CXmlValidator::validateSchema()
    {
       std::cout << std::endl;
       xercesc::XMLPlatformUtils::Initialize();
    
       std::string xsdFile = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>...";
    
       xercesc::SAX2XMLReader *parser = xercesc::XMLReaderFactory::createXMLReader();
       xercesc::ErrorHandler *handler = new CErrorHandler();
    
       xercesc::MemBufInputSource inMemorySchemaSource(reinterpret_cast<const XMLByte*>(xsdFile.c_str()), xsdFile.size (), "/schema.xsd");
    
       parser->loadGrammar(inMemorySchemaSource, xercesc::Grammar::SchemaGrammarType, true);
       parser->setFeature(xercesc::XMLUni::fgXercesUseCachedGrammarInParse, true);
       parser->setFeature(xercesc::XMLUni::fgSAX2CoreValidation, true);
       parser->setFeature(xercesc::XMLUni::fgSAX2CoreNameSpaces, true);
       parser->setProperty(xercesc::XMLUni::fgXercesSchemaExternalNoNameSpaceSchemaLocation, const_cast<void*>(static_cast<const void*>("")));
       parser->setErrorHandler(handler);
       parser->parse("file.xml");
    
       if (parser->getErrorCount() != 0)
       {
          std::cout << "ERROR: XML file '" << mXMLFilePath << "' not confirm to the schema" << std::endl;
          return false;
       }
       else
       {
          return true;
       }
    }
    

    Here is correct realizations of error handler and validator classes, if somebody will need them