//----------------------------------------- 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; }
/* {{{ _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; }
/* 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; }
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); }