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:
 *    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;
  }
}
    /*!
     * \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;
    }
Beispiel #4
0
/* 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;
}
Beispiel #5
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);
}