PageRenderTime 25ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/libxml++/validators/schemavalidator.cpp

https://bitbucket.org/khurley/libxml
C++ | 234 lines | 122 code | 36 blank | 76 comment | 5 complexity | 4dcd222a6abc58d8b259dc32de4e038a MD5 | raw file
  1. ///==========================================================================
  2. /// \file schemavalidator.cpp
  3. /// \brief Validate an XML file using a schema
  4. /// \date 4/5/2005
  5. /// \author Kyle Swaim
  6. ///==========================================================================
  7. #ifdef USE_PRECOMPILED
  8. #include "libxml++/libxml++.h"
  9. #else
  10. #include "libxml++/validators/dtdvalidator.h"
  11. #include "libxml++/dtd.h"
  12. #include "libxml++/nodes/element.h"
  13. #include "libxml++/nodes/textnode.h"
  14. #include "libxml++/nodes/commentnode.h"
  15. #include "libxml++/keepblanks.h"
  16. #include "libxml++/exceptions/internal_error.h"
  17. #include "libxml++/io/istreamparserinputbuffer.h"
  18. #include <libxml/parserInternals.h>//For xmlCreateFileParserCtxt().
  19. #include <libxml/xmlschemas.h>
  20. #include <sstream>
  21. #include <iostream>
  22. #include <stdarg.h>
  23. #endif
  24. #include <string.h>
  25. #include "schemavalidator.h"
  26. namespace xmlpp
  27. {
  28. /// \brief Default Constructor
  29. SchemaValidator::SchemaValidator()
  30. {
  31. m_Schema = NULL;
  32. }
  33. /// \brief Constructor
  34. SchemaValidator::SchemaValidator( const uniStr::ustring& file )
  35. {
  36. m_Schema = NULL;
  37. parse_subset( "", file );
  38. }
  39. /// \brief Constructor
  40. SchemaValidator::SchemaValidator( const uniStr::ustring& external, const uniStr::ustring& system )
  41. {
  42. m_Schema = NULL;
  43. parse_subset( external, system );
  44. }
  45. /// \brief Destructor
  46. SchemaValidator::~SchemaValidator()
  47. {
  48. release_underlying();
  49. Validator::release_underlying();
  50. }
  51. /// \brief Parse a subset of a file
  52. /// \param
  53. /// \param
  54. void SchemaValidator::parse_subset( const uniStr::ustring& external, const uniStr::ustring& system )
  55. {
  56. release_underlying(); // Free any existing dtd.
  57. // no schema parser
  58. // xmlSchema* schema = xmlParseDTD( external.empty() ? 0 : (const xmlChar *)external.c_str(),
  59. // system.empty() ? 0 : (const xmlChar *)system.c_str() );
  60. //if( ! schema )
  61. // throw parse_error("Schema could not be parsed");
  62. //m_Schema = static_cast<Schema*>(schema->_private);
  63. }
  64. /// \brief Parse a file
  65. /// \param filename - the name of the file to parse
  66. void SchemaValidator::parse_file( const uniStr::ustring& filename )
  67. {
  68. parse_subset( "", filename );
  69. }
  70. /// \brief Parse a section of memory
  71. /// param contents - The section of memory to parse
  72. void SchemaValidator::parse_memory( const uniStr::ustring& contents )
  73. {
  74. // Prepare an istream with buffer
  75. std::istringstream is( contents );
  76. parse_stream( is );
  77. }
  78. /// \brief Parse an IO stream
  79. /// \param in - The input stream to parse
  80. void SchemaValidator::parse_stream( std::istream& in )
  81. {
  82. release_underlying(); //Free any existing document.
  83. IStreamParserInputBuffer ibuff( in );
  84. // no schema parser
  85. //xmlSchema* schema = xmlIOParseDTD( 0, ibuff.cobj(), XML_CHAR_ENCODING_UTF8 );
  86. //if( !schema )
  87. // throw parse_error("Schema could not be parsed");
  88. //m_Schema = static_cast<Schema*>(schema->_private);
  89. }
  90. void SchemaValidator::set_schema( Schema *pSchema )
  91. {
  92. m_Schema = pSchema;
  93. }
  94. /// \brief Get the schema
  95. /// \return The schema
  96. Schema* SchemaValidator::get_schema()
  97. {
  98. return m_Schema;
  99. }
  100. /// \brief Get the schema
  101. /// \return The schema
  102. const Schema* SchemaValidator::get_schema() const
  103. {
  104. return m_Schema;
  105. }
  106. /// \brief Validate a document against the schema
  107. /// \param doc - The document to validate
  108. /// \return true if the doc is valid, false if it is not
  109. bool SchemaValidator::validate( Document* doc )
  110. {
  111. xmlSchemaValidCtxtPtr pValidCtxt = xmlSchemaNewValidCtxt( m_Schema->cobj() );
  112. // TODO: send userdata to error/warning callbacks for proper error message output, ie. log ptr
  113. xmlSchemaSetValidErrors( pValidCtxt, xmlSchemaValidityErrorFunc, xmlSchemaValidityWarningFunc, NULL );
  114. int iRetVal = xmlSchemaValidateDoc( pValidCtxt, doc->cobj() );
  115. // * Returns 0 if the document is schemas valid, a positive error code
  116. // * number otherwise and -1 in case of internal or API error.
  117. xmlSchemaFreeValidCtxt( pValidCtxt );
  118. return (iRetVal == 0);
  119. /*
  120. // A context is required at this stage only
  121. if( !valid_ )
  122. valid_ = xmlNewValidCtxt();
  123. if( !valid_ )
  124. {
  125. throw internal_error( "Couldn't create parsing context" );
  126. }
  127. if( !doc )
  128. throw internal_error( "Document pointer cannot be 0" );
  129. initialize_valid();
  130. #pragma warning( disable: 4800 )
  131. //bool res = (bool)xmlValidateDtd( valid_, (xmlDoc*)doc->cobj(), dtd_->cobj() );
  132. #pragma warning( default: 4800 )
  133. // if(res == 0)
  134. // {
  135. // check_for_exception();
  136. // throw validity_error("Document failed Dtd validation");
  137. // }
  138. // return res;
  139. return true;
  140. */
  141. }
  142. bool SchemaValidator::validate( Node *pNode )
  143. {
  144. if (!pNode)
  145. return false;
  146. xmlSchemaValidCtxtPtr pValidCtxt = xmlSchemaNewValidCtxt( m_Schema->cobj() );
  147. // TODO: send userdata to error/warning callbacks for proper error message output, ie. log ptr
  148. xmlSchemaSetValidErrors( pValidCtxt, xmlSchemaValidityErrorFunc, xmlSchemaValidityWarningFunc, NULL );
  149. int iRetVal = xmlSchemaValidateOneElement( pValidCtxt, pNode->cobj() );
  150. // * Returns 0 if the document is schemas valid, a positive error code
  151. // * number otherwise and -1 in case of internal or API error.
  152. xmlSchemaFreeValidCtxt( pValidCtxt );
  153. return (iRetVal == 0);
  154. }
  155. void SchemaValidator::xmlSchemaValidityErrorFunc (void *ctx, const char *msg, ...)
  156. {
  157. va_list marker;
  158. va_start( marker, msg );
  159. char szBuffer[2048];
  160. #ifdef WIN32
  161. vsnprintf( szBuffer, 2048, msg, marker );
  162. // TODO: better output for errors and warnings
  163. printf( "Schema Validation Error: %s", szBuffer );
  164. #else
  165. // TODO: implement vsnprintf for other platforms
  166. strcpy( szBuffer, "Unknown error." );
  167. #endif
  168. va_end( marker );
  169. }
  170. void SchemaValidator::xmlSchemaValidityWarningFunc (void *ctx, const char *msg, ...)
  171. {
  172. va_list marker;
  173. va_start( marker, msg );
  174. char szBuffer[2048];
  175. #ifdef WIN32
  176. vsnprintf( szBuffer, 2048, msg, marker );
  177. printf( "Schema Validation Warning: %s", szBuffer );
  178. #else
  179. // TODO: implement vsnprintf for other platforms
  180. strcpy( szBuffer, "Unknown warning." );
  181. #endif
  182. va_end( marker );
  183. }
  184. /// \brief Release the underlying schema representation
  185. void SchemaValidator::release_underlying()
  186. {
  187. if( m_Schema != NULL )
  188. {
  189. m_Schema = NULL;
  190. }
  191. }
  192. } // namespace xmlpp