Xerces XSD validate sample

ref https://stackoverflow.com/questions/22565157/xml-file-validation-with-in-memory-schema-in-xerces-c


#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(const char *xsdFileName, const char *xmlFileName);
private:
   /** Xml file */
   std::string mXMLFilePath;
};


CXmlValidator::CXmlValidator():
   mXMLFilePath("")
{
}

CXmlValidator::~CXmlValidator()
{
}

void CXmlValidator::setFilePath(const std::string &filePath)
{
   mXMLFilePath = filePath;
}

bool CXmlValidator::validateSchema(const char *xsdFileName, const char *xmlFileName)
{
   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->loadGrammar(xsdFileName, 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(xmlFileName);

   if (parser->getErrorCount() != 0)
   {
      std::cout << "ERROR: XML file '" << mXMLFilePath << "' not confirm to the schema" << std::endl;
      return false;
   }
   else
   {
      return true;
   }
}



int main (int argc, char* args[])
{

    CXmlValidator xval;
    xval.validateSchema("test.xsd", "sample.xml");

    return 0;
}




test.xsd
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="infos">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="info" maxOccurs="unbounded" minOccurs="0">
          <xs:complexType>
            <xs:sequence>
              <xs:element type="xs:string" name="id"/>
              <xs:element type="xs:byte" name="status"/>
              <xs:element name="datas" minOccurs="0">
                <xs:complexType mixed="true">
                  <xs:sequence>
                    <xs:element name="data" maxOccurs="unbounded" minOccurs="0">
                      <xs:complexType>
                        <xs:simpleContent>
                          <xs:extension base="xs:string">
                            <xs:attribute type="xs:byte" name="type" use="optional"/>
                            <xs:attribute type="xs:string" name="value" use="optional"/>
                          </xs:extension>
                        </xs:simpleContent>
                      </xs:complexType>
                    </xs:element>
                  </xs:sequence>
                </xs:complexType>
              </xs:element>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>


sample.xml

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE infos [
  <!ELEMENT infos (info)*>
  <!ELEMENT info (id, status, datas?)>
  <!ELEMENT id (#PCDATA)>
  <!ELEMENT status (#PCDATA)>
  <!ELEMENT datas (data)*>
  <!ELEMENT data (#PCDATA)>
  <!ATTLIST data
    type CDATA #REQUIRED
    value CDATA #REQUIRED>
  ]>
<infos>
 <info>
  <id>id1</id>
  <status>0</status>
  <datas>
   <data type="1" value="user@123"/>
  </datas>
 </info>

 <info>
  <id>id2</id>
  <status>1</status>
 </info>
 <info>
  <id>id3</id>
  <status>2</status>
  <datas></datas>
 </info>
 <info>
  <id>id4</id>
  <status>3</status>
  <datas>
   <data type="1" value="user@123"/>
   <data type="2" value="user@12345678"/>
   <data type="5" value="12345678"/>
  </datas>
 </info>
</infos>




留言

熱門文章