//----------------------------------------- bool RngValidator::run(const std::string& xml_file_pathname, const std::string& rng_file_pathname) //----------------------------------------- { // TODO handle multiple RNG files (eg viz) // RELAX NG Parser Context xmlRelaxNGParserCtxtPtr ctxt = xmlRelaxNGNewParserCtxt(rng_file_pathname.c_str()); xmlRelaxNGSetParserErrors(ctxt, (xmlRelaxNGValidityErrorFunc)RngValidator::rngErr, (xmlRelaxNGValidityWarningFunc)RngValidator::rngWarn, NULL); xmlRelaxNGPtr schema = xmlRelaxNGParse(ctxt); xmlRelaxNGFreeParserCtxt(ctxt); xmlTextReaderPtr reader = xmlNewTextReaderFilename(xml_file_pathname.c_str()); xmlTextReaderRelaxNGSetSchema(reader, schema); xmlTextReaderSetErrorHandler(reader, (xmlTextReaderErrorFunc)RngValidator::readerErr, NULL); xmlTextReaderSetStructuredErrorHandler(reader, (xmlStructuredErrorFunc)RngValidator::structErr, NULL); while (xmlTextReaderRead(reader)); const bool valid = xmlTextReaderIsValid(reader) == 1; xmlFreeTextReader(reader); xmlRelaxNGFree(schema); return valid; }
/*! * \brief Private constructor from a libxml pointer * * Do the real configuration from a libxml pointer * \param pctxt[in]: lib xml document pointer */ void QRelaxNGvalidator::finish(const void * pctxt) { // Parse schema this->rng = xmlRelaxNGParse((xmlRelaxNGParserCtxtPtr)pctxt); xmlRelaxNGFreeParserCtxt((xmlRelaxNGParserCtxtPtr)pctxt); if(!rng) { goto schemaerror; } // Create a validation context vctxt = xmlRelaxNGNewValidCtxt((xmlRelaxNGPtr)this->rng); if(!vctxt) { goto contexterror; } /* Ask the validation parser to return error */ xmlRelaxNGSetValidErrors((xmlRelaxNGValidCtxtPtr)this->vctxt, (xmlRelaxNGValidityErrorFunc) fprintf, (xmlRelaxNGValidityWarningFunc) fprintf, stderr); return; schemaerror: this->raiseError(QString("Schema ") + this->filename + QString(" has an error")); return; contexterror: this->raiseError(QString("Could not create validation context for ") + this->filename + QString("schema")); xmlRelaxNGFree((xmlRelaxNGPtr)this->rng); return; }
RelaxNGSchema(const std::string& grammar) { xmlRelaxNGParserCtxtPtr ctxt = xmlRelaxNGNewMemParserCtxt(grammar.c_str(), (int)grammar.size()); m_Schema = xmlRelaxNGParse(ctxt); xmlRelaxNGFreeParserCtxt(ctxt); if (m_Schema == NULL) LOGERROR("RelaxNGValidator: Failed to compile schema"); }
void RelaxNGSchema::parse_context(_xmlRelaxNGParserCtxt* context) { xmlResetLastError(); release_underlying(); if (!context) throw parse_error("RelaxNGSchema::parse_context(): Could not create parser context.\n" + format_xml_error()); RelaxNGSchemaParserContextHolder holder(context); pimpl_->schema = xmlRelaxNGParse(context); if (!pimpl_->schema) throw parse_error("RelaxNGSchema::parse_context(): Schema could not be parsed.\n" + format_xml_error()); }
/* * call-seq: * from_document(doc) * * Create a new RelaxNG schema from the Nokogiri::XML::Document +doc+ */ static VALUE from_document(VALUE klass, VALUE document) { xmlDocPtr doc; xmlRelaxNGParserCtxtPtr ctx; xmlRelaxNGPtr schema; VALUE errors; VALUE rb_schema; Data_Get_Struct(document, xmlDoc, doc); /* In case someone passes us a node. ugh. */ doc = doc->doc; ctx = xmlRelaxNGNewDocParserCtxt(doc); errors = rb_ary_new(); Nokogiri_install_error_catcher(errors); #ifdef HAVE_XMLRELAXNGSETPARSERSTRUCTUREDERRORS xmlRelaxNGSetParserStructuredErrors( ctx, Nokogiri_error_array_pusher, (void *)errors ); #endif schema = xmlRelaxNGParse(ctx); Nokogiri_remove_error_catcher(); if(NULL == schema) { xmlErrorPtr error = xmlGetLastError(); if(error) Nokogiri_error_raise(NULL, error); else rb_raise(rb_eRuntimeError, "Could not parse document"); return Qnil; } rb_schema = Data_Wrap_Struct(klass, 0, dealloc, schema); rb_iv_set(rb_schema, "@errors", errors); return rb_schema; }
XMLValidationRelaxNG::XMLValidationRelaxNG(const char *path, std::string * error): XMLValidation() { char *expandedPath = expandPathVariable(const_cast < char *>(path)); if (expandedPath) { xmlRelaxNGParserCtxt *pctxt = xmlRelaxNGNewParserCtxt(expandedPath); FREE(expandedPath); if (!pctxt) { if (errorBuffer) { delete errorBuffer; } errorBuffer = new std::string(gettext("Cannot create a validation context")); *error = *errorBuffer; } else { validationFile = (void *)xmlRelaxNGParse(pctxt); xmlRelaxNGFreeParserCtxt(pctxt); if (!validationFile) { if (errorBuffer) { delete errorBuffer; } errorBuffer = new std::string(gettext("Cannot parse the Relax NG grammar")); *error = *errorBuffer; } else { openValidationFiles.push_back(this); } } } else { *error = std::string(gettext("Invalid file name: ")) + std::string(path); } scope->registerPointers(validationFile, this); id = scope->getVariableId(*this); }
/* {{{ _xmlreader_get_relaxNG */ static xmlRelaxNGPtr _xmlreader_get_relaxNG(char *source, size_t source_len, size_t type, xmlRelaxNGValidityErrorFunc error_func, xmlRelaxNGValidityWarningFunc warn_func) { char *valid_file = NULL; xmlRelaxNGParserCtxtPtr parser = NULL; xmlRelaxNGPtr sptr; char resolved_path[MAXPATHLEN + 1]; switch (type) { case XMLREADER_LOAD_FILE: valid_file = _xmlreader_get_valid_file_path(source, resolved_path, MAXPATHLEN ); if (!valid_file) { return NULL; } parser = xmlRelaxNGNewParserCtxt(valid_file); break; case XMLREADER_LOAD_STRING: parser = xmlRelaxNGNewMemParserCtxt(source, source_len); /* If loading from memory, we need to set the base directory for the document but it is not apparent how to do that for schema's */ break; default: return NULL; } if (parser == NULL) { return NULL; } if (error_func || warn_func) { xmlRelaxNGSetParserErrors(parser, (xmlRelaxNGValidityErrorFunc) error_func, (xmlRelaxNGValidityWarningFunc) warn_func, parser); } sptr = xmlRelaxNGParse(parser); xmlRelaxNGFreeParserCtxt(parser); return sptr; }
static xmlRelaxNGPtr _xmlreader_get_relaxNG(String source, int type, xmlRelaxNGValidityErrorFunc error_func, xmlRelaxNGValidityWarningFunc warn_func ) { xmlRelaxNGParserCtxtPtr parser = NULL; xmlRelaxNGPtr sptr; String valid_file; switch (type) { case XMLREADER_LOAD_FILE: valid_file = _xmlreader_get_valid_file_path(source.c_str()); if (valid_file.empty()) { return NULL; } parser = xmlRelaxNGNewParserCtxt(valid_file.c_str()); break; case XMLREADER_LOAD_STRING: parser = xmlRelaxNGNewMemParserCtxt(source.data(), source.size()); /* If loading from memory, we need to set the base directory for the document but it is not apparent how to do that for schema's */ break; default: return NULL; } if (parser == NULL) { return NULL; } if (error_func || warn_func) { xmlRelaxNGSetParserErrors(parser, (xmlRelaxNGValidityErrorFunc) error_func, (xmlRelaxNGValidityWarningFunc) warn_func, parser); } sptr = xmlRelaxNGParse(parser); xmlRelaxNGFreeParserCtxt(parser); return sptr; }
/* * call-seq: * read_memory(string) * * Create a new RelaxNG from the contents of +string+ */ static VALUE read_memory(VALUE klass, VALUE content) { xmlRelaxNGParserCtxtPtr ctx = xmlRelaxNGNewMemParserCtxt( (const char *)StringValuePtr(content), (int)RSTRING_LEN(content) ); xmlRelaxNGPtr schema; VALUE errors = rb_ary_new(); VALUE rb_schema; Nokogiri_install_error_catcher(errors); #ifdef HAVE_XMLRELAXNGSETPARSERSTRUCTUREDERRORS xmlRelaxNGSetParserStructuredErrors( ctx, Nokogiri_error_array_pusher, (void *)errors ); #endif schema = xmlRelaxNGParse(ctx); Nokogiri_remove_error_catcher(); xmlRelaxNGFreeParserCtxt(ctx); if(NULL == schema) { xmlErrorPtr error = xmlGetLastError(); if(error) Nokogiri_error_raise(NULL, error); else rb_raise(rb_eRuntimeError, "Could not parse document"); return Qnil; } rb_schema = Data_Wrap_Struct(klass, 0, dealloc, schema); rb_iv_set(rb_schema, "@errors", errors); return rb_schema; }
/** * Parse elements from the configuration file. * */ ods_status parse_file_check(const char* cfgfile, const char* rngfile) { xmlDocPtr doc = NULL; xmlDocPtr rngdoc = NULL; xmlRelaxNGParserCtxtPtr rngpctx = NULL; xmlRelaxNGValidCtxtPtr rngctx = NULL; xmlRelaxNGPtr schema = NULL; if (!cfgfile || !rngfile) { ods_log_error("[%s] no cfgfile or rngfile", parser_str); return ODS_STATUS_ASSERT_ERR; } ods_log_assert(cfgfile); ods_log_assert(rngfile); ods_log_debug("[%s] check cfgfile %s with rngfile %s", parser_str, cfgfile, rngfile); /* Load XML document */ doc = xmlParseFile(cfgfile); if (doc == NULL) { ods_log_error("[%s] unable to read cfgfile %s", parser_str, cfgfile); return ODS_STATUS_XML_ERR; } /* Load rng document */ rngdoc = xmlParseFile(rngfile); if (rngdoc == NULL) { ods_log_error("[%s] unable to read rngfile %s", parser_str, rngfile); xmlFreeDoc(doc); return ODS_STATUS_XML_ERR; } /* Create an XML RelaxNGs parser context for the relax-ng document. */ rngpctx = xmlRelaxNGNewDocParserCtxt(rngdoc); if (rngpctx == NULL) { xmlFreeDoc(rngdoc); xmlFreeDoc(doc); ods_log_error("[%s] unable to create XML RelaxNGs parser context", parser_str); return ODS_STATUS_XML_ERR; } /* Parse a schema definition resource and * build an internal XML schema structure. */ schema = xmlRelaxNGParse(rngpctx); if (schema == NULL) { ods_log_error("[%s] unable to parse a schema definition resource", parser_str); xmlRelaxNGFreeParserCtxt(rngpctx); xmlFreeDoc(rngdoc); xmlFreeDoc(doc); return ODS_STATUS_PARSE_ERR; } /* Create an XML RelaxNGs validation context. */ rngctx = xmlRelaxNGNewValidCtxt(schema); if (rngctx == NULL) { ods_log_error("[%s] unable to create RelaxNGs validation context", parser_str); xmlRelaxNGFree(schema); xmlRelaxNGFreeParserCtxt(rngpctx); xmlFreeDoc(rngdoc); xmlFreeDoc(doc); return ODS_STATUS_RNG_ERR; } /* Validate a document tree in memory. */ /* better not check: if not correct, this will segfault. status = xmlRelaxNGValidateDoc(rngctx,doc); if (status != 0) { ods_log_error("[%s] cfgfile validation failed %s", parser_str, cfgfile); xmlRelaxNGFreeValidCtxt(rngctx); xmlRelaxNGFree(schema); xmlRelaxNGFreeParserCtxt(rngpctx); xmlFreeDoc(rngdoc); xmlFreeDoc(doc); return ODS_STATUS_RNG_ERR; } */ xmlRelaxNGFreeValidCtxt(rngctx); xmlRelaxNGFree(schema); xmlRelaxNGFreeParserCtxt(rngpctx); xmlFreeDoc(rngdoc); xmlFreeDoc(doc); return ODS_STATUS_OK; }
/* * call-seq: * XML::Relaxng.new(relaxng_uri) -> relaxng * * Create a new relaxng from the specified URI. */ VALUE ruby_xml_relaxng_init_from_uri(VALUE class, VALUE uri) { xmlRelaxNGParserCtxtPtr parser; ruby_xml_relaxng *relaxng; Check_Type(uri, T_STRING); parser = xmlRelaxNGNewParserCtxt(StringValuePtr(uri)); relaxng = ALLOC(ruby_xml_relaxng); relaxng->relaxng = xmlRelaxNGParse(parser); xmlRelaxNGFreeParserCtxt(parser); return Data_Wrap_Struct(cXMLRelaxNG, ruby_xml_relaxng_mark, ruby_xml_relaxng_free, relaxng); } /* * call-seq: * XML::RelaxNG.document(document) -> relaxng * * Create a new relaxng from the specified document. */ VALUE ruby_xml_relaxng_init_from_document(VALUE class, VALUE document) { ruby_xml_document_t *rdoc; ruby_xml_relaxng *relaxng;
static inline std::auto_ptr<SystemState> createSystemFromConfig(const char *filename, const XESector *configSector) { uint64_t length = configSector->getLength(); const scoped_array<char> buf(new char[length + 1]); if (!configSector->getData(buf.get())) { std::cerr << "Error reading config from \"" << filename << "\"" << std::endl; std::exit(1); } if (length < 8) { std::cerr << "Error unexpected config config sector length" << std::endl; std::exit(1); } length -= 8; buf[length] = '\0'; /* * this initialize the library and check potential ABI mismatches * between the version it was compiled for and the actual shared * library used. */ LIBXML_TEST_VERSION xmlDoc *doc = xmlReadDoc((xmlChar*)buf.get(), "config.xml", NULL, 0); xmlRelaxNGParserCtxtPtr schemaContext = xmlRelaxNGNewMemParserCtxt(configSchema, sizeof(configSchema)); xmlRelaxNGPtr schema = xmlRelaxNGParse(schemaContext); xmlRelaxNGValidCtxtPtr validationContext = xmlRelaxNGNewValidCtxt(schema); if (xmlRelaxNGValidateDoc(validationContext, doc) != 0) { std::exit(1); } xmlNode *root = xmlDocGetRootElement(doc); xmlNode *system = findChild(root, "System"); xmlNode *nodes = findChild(system, "Nodes"); std::auto_ptr<SystemState> systemState(new SystemState); std::map<long,Node*> nodeNumberMap; for (xmlNode *child = nodes->children; child; child = child->next) { if (child->type != XML_ELEMENT_NODE || strcmp("Node", (char*)child->name) != 0) continue; systemState->addNode(createNodeFromConfig(child, nodeNumberMap)); } xmlNode *connections = findChild(system, "Connections"); for (xmlNode *child = connections->children; child; child = child->next) { if (child->type != XML_ELEMENT_NODE || strcmp("SLink", (char*)child->name) != 0) continue; long nodeID1, link1, nodeID2, link2; if (!parseXLinkEnd(findAttribute(child, "end1"), nodeID1, link1)) { std::cerr << "Failed to parse \"end1\" attribute" << std::endl; std::exit(1); } if (!parseXLinkEnd(findAttribute(child, "end2"), nodeID2, link2)) { std::cerr << "Failed to parse \"end2\" attribute" << std::endl; std::exit(1); } Node *node1 = lookupNodeChecked(nodeNumberMap, nodeID1); if (link1 >= node1->getNumXLinks()) { std::cerr << "Invalid sLink number " << link1 << std::endl; std::exit(1); } Node *node2 = lookupNodeChecked(nodeNumberMap, nodeID2); if (link2 >= node2->getNumXLinks()) { std::cerr << "Invalid sLink number " << link2 << std::endl; std::exit(1); } node1->connectXLink(link1, node2, link2); node2->connectXLink(link2, node1, link1); } xmlNode *jtag = findChild(system, "JtagChain"); unsigned jtagIndex = 0; for (xmlNode *child = jtag->children; child; child = child->next) { if (child->type != XML_ELEMENT_NODE || strcmp("Node", (char*)child->name) != 0) continue; long nodeID = readNumberAttribute(child, "id"); lookupNodeChecked(nodeNumberMap, nodeID)->setJtagIndex(jtagIndex++); } systemState->finalize(); xmlFreeDoc(doc); xmlCleanupParser(); return systemState; }
/* Check an XML file against its rng */ int check_rng(const char *filename, const char *rngfilename) { xmlDocPtr doc = NULL; xmlDocPtr rngdoc = NULL; xmlRelaxNGParserCtxtPtr rngpctx = NULL; xmlRelaxNGValidCtxtPtr rngctx = NULL; xmlRelaxNGPtr schema = NULL; if (verbose) { dual_log("DEBUG: About to check XML validity in %s\n", filename); } /* Load XML document */ doc = xmlParseFile(filename); if (doc == NULL) { dual_log("ERROR: unable to parse file \"%s\"\n", filename); /* Maybe the file doesn't exist? */ check_file(filename, "Configuration file"); return(1); } /* Load rng document */ rngdoc = xmlParseFile(rngfilename); if (rngdoc == NULL) { dual_log("ERROR: unable to parse file \"%s\"\n", rngfilename); /* Maybe the file doesn't exist? */ check_file(rngfilename, "RNG file"); xmlFreeDoc(doc); return(1); } /* Create an XML RelaxNGs parser context for the relax-ng document. */ rngpctx = xmlRelaxNGNewDocParserCtxt(rngdoc); if (rngpctx == NULL) { dual_log("ERROR: unable to create XML RelaxNGs parser context\n"); xmlFreeDoc(doc); xmlFreeDoc(rngdoc); return(1); } xmlRelaxNGSetParserErrors(rngpctx, (xmlRelaxNGValidityErrorFunc) fprintf, (xmlRelaxNGValidityWarningFunc) fprintf, stderr); /* parse a schema definition resource and build an internal XML Shema struture which can be used to validate instances. */ schema = xmlRelaxNGParse(rngpctx); if (schema == NULL) { dual_log("ERROR: unable to parse a schema definition resource\n"); xmlRelaxNGFreeParserCtxt(rngpctx); xmlFreeDoc(doc); xmlFreeDoc(rngdoc); return(1); } /* Create an XML RelaxNGs validation context based on the given schema */ rngctx = xmlRelaxNGNewValidCtxt(schema); if (rngctx == NULL) { dual_log("ERROR: unable to create RelaxNGs validation context based on the schema\n"); xmlRelaxNGFree(schema); xmlRelaxNGFreeParserCtxt(rngpctx); xmlFreeDoc(doc); xmlFreeDoc(rngdoc); return(1); } xmlRelaxNGSetValidErrors(rngctx, (xmlRelaxNGValidityErrorFunc) fprintf, (xmlRelaxNGValidityWarningFunc) fprintf, stderr); /* Validate a document tree in memory. */ if (xmlRelaxNGValidateDoc(rngctx,doc) != 0) { dual_log("ERROR: %s fails to validate\n", filename); xmlRelaxNGFreeValidCtxt(rngctx); xmlRelaxNGFree(schema); xmlRelaxNGFreeParserCtxt(rngpctx); xmlFreeDoc(doc); xmlFreeDoc(rngdoc); return(1); } xmlRelaxNGFreeValidCtxt(rngctx); xmlRelaxNGFree(schema); xmlRelaxNGFreeParserCtxt(rngpctx); xmlFreeDoc(doc); xmlFreeDoc(rngdoc); return 0; }
/** * This is the main function for 'validate' option */ int valMain(int argc, char **argv) { int start; static valOptions ops; static ErrorInfo errorInfo; int invalidFound = 0; int options = XML_PARSE_DTDLOAD | XML_PARSE_DTDATTR; if (argc <= 2) valUsage(argc, argv, EXIT_BAD_ARGS); valInitOptions(&ops); start = valParseOptions(&ops, argc, argv); if (ops.nonet) options |= XML_PARSE_NONET; errorInfo.verbose = ops.err; xmlSetStructuredErrorFunc(&errorInfo, reportError); xmlLineNumbersDefault(1); if (ops.dtd) { /* xmlReader doesn't work with external dtd, have to use SAX * interface */ int i; for (i=start; i<argc; i++) { xmlDocPtr doc; int ret; ret = 0; doc = NULL; errorInfo.filename = argv[i]; doc = xmlReadFile(argv[i], NULL, options); if (doc) { /* TODO: precompile DTD once */ ret = valAgainstDtd(&ops, ops.dtd, doc, argv[i]); xmlFreeDoc(doc); } else { ret = 1; /* Malformed XML or could not open file */ if ((ops.listGood < 0) && !ops.show_val_res) { fprintf(stdout, "%s\n", argv[i]); } } if (ret) invalidFound = 1; if (ops.show_val_res) { if (ret == 0) fprintf(stdout, "%s - valid\n", argv[i]); else fprintf(stdout, "%s - invalid\n", argv[i]); } } } else if (ops.schema || ops.relaxng || ops.embed || ops.wellFormed) { int i; xmlTextReaderPtr reader = NULL; #ifdef LIBXML_SCHEMAS_ENABLED xmlSchemaPtr schema = NULL; xmlSchemaParserCtxtPtr schemaParserCtxt = NULL; xmlSchemaValidCtxtPtr schemaCtxt = NULL; xmlRelaxNGPtr relaxng = NULL; xmlRelaxNGParserCtxtPtr relaxngParserCtxt = NULL; /* there is no xmlTextReaderRelaxNGValidateCtxt() !? */ /* TODO: Do not print debug stuff */ if (ops.schema) { schemaParserCtxt = xmlSchemaNewParserCtxt(ops.schema); if (!schemaParserCtxt) { invalidFound = 2; goto schemaCleanup; } errorInfo.filename = ops.schema; schema = xmlSchemaParse(schemaParserCtxt); if (!schema) { invalidFound = 2; goto schemaCleanup; } xmlSchemaFreeParserCtxt(schemaParserCtxt); schemaCtxt = xmlSchemaNewValidCtxt(schema); if (!schemaCtxt) { invalidFound = 2; goto schemaCleanup; } } else if (ops.relaxng) { relaxngParserCtxt = xmlRelaxNGNewParserCtxt(ops.relaxng); if (!relaxngParserCtxt) { invalidFound = 2; goto schemaCleanup; } errorInfo.filename = ops.relaxng; relaxng = xmlRelaxNGParse(relaxngParserCtxt); if (!relaxng) { invalidFound = 2; goto schemaCleanup; } } #endif /* LIBXML_SCHEMAS_ENABLED */ for (i=start; i<argc; i++) { int ret = 0; if (ops.embed) options |= XML_PARSE_DTDVALID; if (!reader) { reader = xmlReaderForFile(argv[i], NULL, options); } else { ret = xmlReaderNewFile(reader, argv[i], NULL, options); } errorInfo.xmlReader = reader; errorInfo.filename = argv[i]; if (reader && ret == 0) { #ifdef LIBXML_SCHEMAS_ENABLED if (schemaCtxt) { ret = xmlTextReaderSchemaValidateCtxt(reader, schemaCtxt, 0); } else if (relaxng) { ret = xmlTextReaderRelaxNGSetSchema(reader, relaxng); } #endif /* LIBXML_SCHEMAS_ENABLED */ if (ret == 0) { do { ret = xmlTextReaderRead(reader); } while (ret == 1); if (ret != -1 && (schema || relaxng || ops.embed)) ret = !xmlTextReaderIsValid(reader); } } else { if (ops.err) fprintf(stderr, "couldn't read file '%s'\n", errorInfo.filename); ret = 1; /* could not open file */ } if (ret) invalidFound = 1; if (!ops.show_val_res) { if ((ops.listGood > 0) && (ret == 0)) fprintf(stdout, "%s\n", argv[i]); if ((ops.listGood < 0) && (ret != 0)) fprintf(stdout, "%s\n", argv[i]); } else { if (ret == 0) fprintf(stdout, "%s - valid\n", argv[i]); else fprintf(stdout, "%s - invalid\n", argv[i]); } } errorInfo.xmlReader = NULL; xmlFreeTextReader(reader); #ifdef LIBXML_SCHEMAS_ENABLED schemaCleanup: xmlSchemaFreeValidCtxt(schemaCtxt); xmlRelaxNGFree(relaxng); xmlSchemaFree(schema); xmlRelaxNGCleanupTypes(); xmlSchemaCleanupTypes(); #endif /* LIBXML_SCHEMAS_ENABLED */ } xmlCleanupParser(); return invalidFound; }
/** * Validation function take first argument as XML type, then check if is * well formated. If so, do the same for RNG document. If both success, check * XML document against RNG schema restrictions. * @return true if pass, false otherwise */ Datum xmlvalidate_rng(PG_FUNCTION_ARGS) { #ifdef USE_LIBXML text *data = NULL; char *rng = NULL; xmlChar *utf8rng = NULL; xmltype *xmldata = NULL; char *xmldataint = NULL; xmlChar *xmldatastr = NULL; bool result = false; int lenxml = -1; // length of xml data int lenrng = -1; // length of xsd data xmlDocPtr doc = NULL; int ret = -1; xmlRelaxNGParserCtxtPtr ctxt = NULL; xmlRelaxNGPtr schema = NULL; xmlRelaxNGValidCtxtPtr validctxt = NULL; // creating xmlChar * from internal xmltype of stored XML xmldata = PG_GETARG_XML_P(0); xmldataint = VARDATA(xmldata); lenxml = VARSIZE(xmldata) - VARHDRSZ; xmldatastr = (xmlChar *) palloc((lenxml + 1) * sizeof(xmlChar)); memcpy(xmldatastr, xmldataint, lenxml); xmldatastr[lenxml] = '\0'; // creating xmlChar* from text representation of XSD data = PG_GETARG_TEXT_P(1); lenrng = VARSIZE(data) - VARHDRSZ; rng = text_to_cstring(data); //encode XML to internal representation with UTF-8, only one used in LibXML utf8rng = pg_do_encoding_conversion((unsigned char*)rng, lenrng, GetDatabaseEncoding(), PG_UTF8); //initialize LibXML structures, if allready done -> do nothing pg_xml_init(); xmlInitParser(); doc = xmlReadMemory((const char *)xmldatastr, lenxml, "include.xml", NULL, 0); if (doc == NULL) { elog(ERROR, "Failed to parse XML document"); PG_RETURN_BOOL (false); } ctxt = xmlRelaxNGNewMemParserCtxt(rng, lenrng); if (ctxt == NULL) { // unable to create parser context elog(ERROR, "Error with creating schema, check if RelaxNG schema is valid"); PG_RETURN_BOOL (false); } schema = xmlRelaxNGParse(ctxt); // parse schema xmlRelaxNGFreeParserCtxt(ctxt); // realease parser context validctxt = xmlRelaxNGNewValidCtxt(schema); if (validctxt == NULL) { // cant create validation context xmlRelaxNGFree(schema); elog(ERROR, "Cant create validation context"); PG_RETURN_BOOL (false); } // set errors to SQL errors xmlRelaxNGSetValidErrors(validctxt, xml_error_handler, NULL, 0); ret = xmlRelaxNGValidateDoc(validctxt, doc); if (ret == 0) { elog(INFO, "Validates"); result = true; } else if (ret > 0) { elog(INFO, "Dont validates"); result = false; } else { elog(INFO, "Validation generated an internal error"); result = false; } xmlRelaxNGFree(schema); xmlRelaxNGFreeValidCtxt(validctxt); xmlFreeDoc(doc); // clean up document in memmory xmlCleanupParser(); // clean up stream parser PG_RETURN_BOOL (result); #else NO_XML_SUPPORT(); PG_RETURN_BOOL (false); #endif }
int main(int argc, char **argv) { int i; int files = 0; xmlRelaxNGPtr schema = NULL; for (i = 1; i < argc ; i++) { #ifdef LIBXML_DEBUG_ENABLED if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug"))) debug++; else #endif #ifdef HAVE_SYS_MMAN_H if ((!strcmp(argv[i], "-memory")) || (!strcmp(argv[i], "--memory"))) { memory++; } else #endif if ((!strcmp(argv[i], "-noout")) || (!strcmp(argv[i], "--noout"))) { noout++; } else if ((!strcmp(argv[i], "-tree")) || (!strcmp(argv[i], "--tree"))) { tree++; } } xmlLineNumbersDefault(1); xmlSubstituteEntitiesDefault(1); for (i = 1; i < argc ; i++) { if (argv[i][0] != '-') { if (schema == NULL) { xmlRelaxNGParserCtxtPtr ctxt; #ifdef HAVE_SYS_MMAN_H if (memory) { int fd; struct stat info; const char *base; if (stat(argv[i], &info) < 0) break; if ((fd = open(argv[i], O_RDONLY)) < 0) break; base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ; if (base == (void *) MAP_FAILED) break; ctxt = xmlRelaxNGNewMemParserCtxt((char *)base,info.st_size); xmlRelaxNGSetParserErrors(ctxt, (xmlRelaxNGValidityErrorFunc) fprintf, (xmlRelaxNGValidityWarningFunc) fprintf, stderr); schema = xmlRelaxNGParse(ctxt); xmlRelaxNGFreeParserCtxt(ctxt); munmap((char *) base, info.st_size); } else #endif { ctxt = xmlRelaxNGNewParserCtxt(argv[i]); xmlRelaxNGSetParserErrors(ctxt, (xmlRelaxNGValidityErrorFunc) fprintf, (xmlRelaxNGValidityWarningFunc) fprintf, stderr); schema = xmlRelaxNGParse(ctxt); xmlRelaxNGFreeParserCtxt(ctxt); } if (schema == NULL) { printf("Relax-NG schema %s failed to compile\n", argv[i]); files = -1; break; } #ifdef LIBXML_OUTPUT_ENABLED #ifdef LIBXML_DEBUG_ENABLED if (debug) xmlRelaxNGDump(stdout, schema); #endif if (tree) xmlRelaxNGDumpTree(stdout, schema); #endif /* LIBXML_OUTPUT_ENABLED */ } else { xmlDocPtr doc; doc = xmlReadFile(argv[i],NULL,0); if (doc == NULL) { fprintf(stderr, "Could not parse %s\n", argv[i]); } else { xmlRelaxNGValidCtxtPtr ctxt; int ret; ctxt = xmlRelaxNGNewValidCtxt(schema); xmlRelaxNGSetValidErrors(ctxt, (xmlRelaxNGValidityErrorFunc) fprintf, (xmlRelaxNGValidityWarningFunc) fprintf, stderr); ret = xmlRelaxNGValidateDoc(ctxt, doc); if (ret == 0) { printf("%s validates\n", argv[i]); } else if (ret > 0) { printf("%s fails to validate\n", argv[i]); } else { printf("%s validation generated an internal error\n", argv[i]); } xmlRelaxNGFreeValidCtxt(ctxt); xmlFreeDoc(doc); } } files ++; } } if (schema != NULL) xmlRelaxNGFree(schema); if (files == 0) { printf("Usage : %s [--debug] [--noout] schemas XMLfiles ...\n", argv[0]); printf("\tParse the HTML files and output the result of the parsing\n"); #ifdef LIBXML_DEBUG_ENABLED printf("\t--debug : dump a debug tree of the in-memory document\n"); #endif printf("\t--noout : do not print the result\n"); printf("\t--tree : print the intermediate Relax-NG document tree\n"); #ifdef HAVE_SYS_MMAN_H printf("\t--memory : test the schemas in memory parsing\n"); #endif } xmlRelaxNGCleanupTypes(); xmlCleanupParser(); xmlMemoryDump(); return(0); }