/* * call-seq: * validate_file(filename) * * Validate a file against this Schema. */ static VALUE validate_file(VALUE self, VALUE rb_filename) { xmlSchemaPtr schema; const char *filename ; Data_Get_Struct(self, xmlSchema, schema); filename = (const char*)StringValuePtr(rb_filename) ; VALUE errors = rb_ary_new(); xmlSchemaValidCtxtPtr valid_ctxt = xmlSchemaNewValidCtxt(schema); if(NULL == valid_ctxt) { // we have a problem rb_raise(rb_eRuntimeError, "Could not create a validation context"); } #ifdef HAVE_XMLSCHEMASETVALIDSTRUCTUREDERRORS xmlSchemaSetValidStructuredErrors( valid_ctxt, Nokogiri_error_array_pusher, (void *)errors ); #endif xmlSchemaValidateFile(valid_ctxt, filename, 0); xmlSchemaFreeValidCtxt(valid_ctxt); return errors; }
/* process interface.cfg file iface - name of the interface to process, or "" for all interfaces dry_run = 1 - test xml without applying anything dry_run = 0 - test + apply */ void opt_process(char *iface, int dry_run) { char cfg_file_name[FILENAME_MAX]; sprintf(cfg_file_name, "%s/%s", KB_CONFIG_DIR, KB_IFACE_CFG); xmlDocPtr document = xmlReadFile(cfg_file_name, NULL, 0); if (NULL == document) { /* can't load */ form_sys_result(KB_ERR, "Can't parse config file"); } else { /* process */ /* check schema compliance */ char schema_file_name[FILENAME_MAX]; sprintf(schema_file_name, "%s/%s", KB_CONFIG_DIR, KB_IFACE_SCHEMA); xmlSchemaParserCtxtPtr schemaParser = xmlSchemaNewParserCtxt(schema_file_name); if (NULL != schemaParser) { xmlSchemaPtr schema = xmlSchemaParse(schemaParser); if (NULL != schema) { xmlSchemaValidCtxtPtr validityContext = xmlSchemaNewValidCtxt(schema); xmlSchemaSetValidErrors(validityContext, schemaErrorCallback, schemaWarningCallback, 0); if (NULL != validityContext) { if (0 != xmlSchemaValidateFile(validityContext, cfg_file_name, 0)) { /* validation error */ schema_error_end(); } else { /* additional processing */ kb_process_xml(document, iface, dry_run); } xmlSchemaFreeValidCtxt(validityContext); } else { form_sys_result(KB_ERR, "Can't create validation context"); } xmlSchemaFree(schema); } else { form_sys_result(KB_ERR, "Can't parse schema"); } xmlSchemaFreeParserCtxt(schemaParser); } else { form_sys_result(KB_ERR, "Can't parse schema file"); } xmlFreeDoc(document); } }
int CPLValidateXML(const char* pszXMLFilename, const char* pszXSDFilename, CPL_UNUSED char** papszOptions) { char szHeader[2048]; CPLString osTmpXSDFilename; if( pszXMLFilename[0] == '<' ) { strncpy(szHeader, pszXMLFilename, sizeof(szHeader)); szHeader[sizeof(szHeader)-1] = '\0'; } else { VSILFILE* fpXML = VSIFOpenL(pszXMLFilename, "rb"); if (fpXML == NULL) { CPLError(CE_Failure, CPLE_OpenFailed, "Cannot open %s", pszXMLFilename); return FALSE; } int nRead = (int)VSIFReadL(szHeader, 1, sizeof(szHeader)-1, fpXML); szHeader[nRead] = '\0'; CPL_IGNORE_RET_VAL(VSIFCloseL(fpXML)); } /* Workaround following bug : "element FeatureCollection: Schemas validity error : Element '{http://www.opengis.net/wfs}FeatureCollection': No matching global declaration available for the validation root" */ /* We create a wrapping XSD that imports the WFS .xsd (and possibly the GML .xsd too) and the application schema */ /* This is a known libxml2 limitation */ if (strstr(szHeader, "<wfs:FeatureCollection") || (strstr(szHeader, "<FeatureCollection") && strstr(szHeader, "xmlns:wfs=\"http://www.opengis.net/wfs\""))) { const char* pszWFSSchemaNamespace = "http://www.opengis.net/wfs"; const char* pszWFSSchemaLocation = NULL; const char* pszGMLSchemaLocation = NULL; if (strstr(szHeader, "wfs/1.0.0/WFS-basic.xsd")) { pszWFSSchemaLocation = "http://schemas.opengis.net/wfs/1.0.0/WFS-basic.xsd"; } else if (strstr(szHeader, "wfs/1.1.0/wfs.xsd")) { pszWFSSchemaLocation = "http://schemas.opengis.net/wfs/1.1.0/wfs.xsd"; } else if (strstr(szHeader, "wfs/2.0/wfs.xsd")) { pszWFSSchemaNamespace = "http://www.opengis.net/wfs/2.0"; pszWFSSchemaLocation = "http://schemas.opengis.net/wfs/2.0/wfs.xsd"; } VSILFILE* fpXSD = VSIFOpenL(pszXSDFilename, "rb"); if (fpXSD == NULL) { CPLError(CE_Failure, CPLE_OpenFailed, "Cannot open %s", pszXSDFilename); return FALSE; } int nRead = (int)VSIFReadL(szHeader, 1, sizeof(szHeader)-1, fpXSD); szHeader[nRead] = '\0'; CPL_IGNORE_RET_VAL(VSIFCloseL(fpXSD)); if (strstr(szHeader, "gml/3.1.1") != NULL && strstr(szHeader, "gml/3.1.1/base/gml.xsd") == NULL) { pszGMLSchemaLocation = "http://schemas.opengis.net/gml/3.1.1/base/gml.xsd"; } if (pszWFSSchemaLocation != NULL) { osTmpXSDFilename = CPLSPrintf("/vsimem/CPLValidateXML_%p_%p.xsd", pszXMLFilename, pszXSDFilename); char* pszEscapedXSDFilename = CPLEscapeString(pszXSDFilename, -1, CPLES_XML); VSILFILE* fpMEM = VSIFOpenL(osTmpXSDFilename, "wb"); CPL_IGNORE_RET_VAL(VSIFPrintfL(fpMEM, "<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">\n")); CPL_IGNORE_RET_VAL(VSIFPrintfL(fpMEM, " <xs:import namespace=\"%s\" schemaLocation=\"%s\"/>\n", pszWFSSchemaNamespace, pszWFSSchemaLocation)); CPL_IGNORE_RET_VAL(VSIFPrintfL(fpMEM, " <xs:import namespace=\"ignored\" schemaLocation=\"%s\"/>\n", pszEscapedXSDFilename)); if (pszGMLSchemaLocation) CPL_IGNORE_RET_VAL(VSIFPrintfL(fpMEM, " <xs:import namespace=\"http://www.opengis.net/gml\" schemaLocation=\"%s\"/>\n", pszGMLSchemaLocation)); CPL_IGNORE_RET_VAL(VSIFPrintfL(fpMEM, "</xs:schema>\n")); CPL_IGNORE_RET_VAL(VSIFCloseL(fpMEM)); CPLFree(pszEscapedXSDFilename); } } CPLXMLSchemaPtr pSchema = CPLLoadXMLSchema(osTmpXSDFilename.size() ? osTmpXSDFilename.c_str() : pszXSDFilename); if (osTmpXSDFilename.size()) VSIUnlink(osTmpXSDFilename); if (pSchema == NULL) return FALSE; xmlSchemaValidCtxtPtr pSchemaValidCtxt; pSchemaValidCtxt = xmlSchemaNewValidCtxt((xmlSchemaPtr)pSchema); if (pSchemaValidCtxt == NULL) { CPLFreeXMLSchema(pSchema); return FALSE; } xmlSchemaSetValidErrors(pSchemaValidCtxt, CPLLibXMLWarningErrorCallback, CPLLibXMLWarningErrorCallback, (void*) pszXMLFilename); bool bValid = false; if( pszXMLFilename[0] == '<' ) { xmlDocPtr pDoc = xmlParseDoc((const xmlChar *)pszXMLFilename); if (pDoc != NULL) { bValid = xmlSchemaValidateDoc(pSchemaValidCtxt, pDoc) == 0; } xmlFreeDoc(pDoc); } else if (!STARTS_WITH(pszXMLFilename, "/vsi")) { bValid = xmlSchemaValidateFile(pSchemaValidCtxt, pszXMLFilename, 0) == 0; } else { char* pszXML = CPLLoadContentFromFile(pszXMLFilename); if (pszXML != NULL) { xmlDocPtr pDoc = xmlParseDoc((const xmlChar *)pszXML); if (pDoc != NULL) { bValid = xmlSchemaValidateDoc(pSchemaValidCtxt, pDoc) == 0; } xmlFreeDoc(pDoc); } CPLFree(pszXML); } xmlSchemaFreeValidCtxt(pSchemaValidCtxt); CPLFreeXMLSchema(pSchema); return bValid; }