Example #1
0
/*
 * 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;
}
Example #2
0
/* 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);
	}
}
Example #3
0
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;
}