/* * call-seq: * document.validate_schema(relaxng) -> (true|false) * * Validate this document against the specified XML::RelaxNG. * * If a block is provided it is used as an error handler for validaten errors. * The block is called with two argument, the message and a flag indication * if the message is an error (true) or a warning (false). */ static VALUE rxml_document_validate_relaxng(VALUE self, VALUE relaxng) { xmlRelaxNGValidCtxtPtr vptr; xmlDocPtr xdoc; xmlRelaxNGPtr xrelaxng; int is_invalid; Data_Get_Struct(self, xmlDoc, xdoc); Data_Get_Struct(relaxng, xmlRelaxNG, xrelaxng); vptr = xmlRelaxNGNewValidCtxt(xrelaxng); xmlRelaxNGSetValidErrors(vptr, (xmlRelaxNGValidityErrorFunc) LibXML_validity_error, (xmlRelaxNGValidityWarningFunc) LibXML_validity_warning, NULL); is_invalid = xmlRelaxNGValidateDoc(vptr, xdoc); xmlRelaxNGFreeValidCtxt(vptr); if (is_invalid) { rxml_raise(&xmlLastError); return Qfalse; } else { return Qtrue; } }
bool XMLValidationRelaxNG::validate(const XMLDocument & doc, std::string * error) const { bool ret; xmlRelaxNGValidCtxt *vctxt = xmlRelaxNGNewValidCtxt((xmlRelaxNG *) validationFile); if (errorBuffer) { delete errorBuffer; } errorBuffer = new std::string(""); if (!vctxt) { errorBuffer->append(gettext("Cannot create a validation context")); *error = *errorBuffer; return false; } xmlRelaxNGSetValidErrors(vctxt, (xmlRelaxNGValidityErrorFunc) XMLValidation::errorFunction, 0, 0); ret = BOOLtobool(xmlRelaxNGValidateDoc(vctxt, doc.getRealDocument())); xmlRelaxNGSetValidErrors(vctxt, 0, 0, 0); xmlRelaxNGFreeValidCtxt(vctxt); if (ret) { *error = *errorBuffer; } return ret == 0; }
/* * call-seq: * validate_document(document) * * Validate a Nokogiri::XML::Document against this RelaxNG schema. */ static VALUE validate_document(VALUE self, VALUE document) { xmlDocPtr doc; xmlRelaxNGPtr schema; VALUE errors; xmlRelaxNGValidCtxtPtr valid_ctxt; Data_Get_Struct(self, xmlRelaxNG, schema); Data_Get_Struct(document, xmlDoc, doc); errors = rb_ary_new(); valid_ctxt = xmlRelaxNGNewValidCtxt(schema); if(NULL == valid_ctxt) { /* we have a problem */ rb_raise(rb_eRuntimeError, "Could not create a validation context"); } #ifdef HAVE_XMLRELAXNGSETVALIDSTRUCTUREDERRORS xmlRelaxNGSetValidStructuredErrors( valid_ctxt, Nokogiri_error_array_pusher, (void *)errors ); #endif xmlRelaxNGValidateDoc(valid_ctxt, doc); xmlRelaxNGFreeValidCtxt(valid_ctxt); return errors; }
/*! * \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; }
bool RelaxNGValidator::ValidateEncoded(xmlDocPtr doc) const { xmlRelaxNGValidCtxtPtr ctxt = xmlRelaxNGNewValidCtxt(m_Schema); xmlRelaxNGSetValidStructuredErrors(ctxt, &relaxNGErrorHandler, NULL); int ret = xmlRelaxNGValidateDoc(ctxt, doc); xmlRelaxNGFreeValidCtxt(ctxt); if (ret == 0) { return true; } else if (ret > 0) { LOGERROR("RelaxNGValidator: Validation failed for '%s'", doc->name); return false; } else { LOGERROR("RelaxNGValidator: Internal error %d", ret); return false; } }
bool RelaxNGValidator::ValidateEncoded(const std::wstring& filename, const std::string& document) { TIMER_ACCRUE(xml_validation); if (!m_Schema) { LOGERROR(L"RelaxNGValidator: No grammar loaded"); return false; } xmlDocPtr doc = xmlReadMemory(document.c_str(), (int)document.size(), utf8_from_wstring(filename).c_str(), NULL, XML_PARSE_NONET); if (doc == NULL) { LOGERROR(L"RelaxNGValidator: Failed to parse document"); return false; } xmlRelaxNGValidCtxtPtr ctxt = xmlRelaxNGNewValidCtxt(m_Schema); int ret = xmlRelaxNGValidateDoc(ctxt, doc); xmlRelaxNGFreeValidCtxt(ctxt); xmlFreeDoc(doc); if (ret == 0) { return true; } else if (ret > 0) { LOGERROR(L"RelaxNGValidator: Validation failed"); return false; } else { LOGERROR(L"RelaxNGValidator: Internal error %d", ret); return false; } }
/** * 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; }
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; }
/** * 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); }