NAN_METHOD(XmlDocument::RngValidate)
{
    Nan::HandleScope scope;

    v8::Local<v8::Array> errors = Nan::New<v8::Array>();
    xmlResetLastError();
    xmlSetStructuredErrorFunc(reinterpret_cast<void *>(&errors),
            XmlSyntaxError::PushToArray);

    XmlDocument* document = Nan::ObjectWrap::Unwrap<XmlDocument>(info.Holder());
    XmlDocument* documentSchema = Nan::ObjectWrap::Unwrap<XmlDocument>(Nan::To<v8::Object>(info[0]).ToLocalChecked());

    xmlRelaxNGParserCtxtPtr parser_ctxt = xmlRelaxNGNewDocParserCtxt(documentSchema->xml_obj);
    if (parser_ctxt == NULL) {
        return Nan::ThrowError("Could not create context for RELAX NG schema parser");
    }

    xmlRelaxNGPtr schema = xmlRelaxNGParse(parser_ctxt);
    if (schema == NULL) {
        return Nan::ThrowError("Invalid RELAX NG schema");
    }

    xmlRelaxNGValidCtxtPtr valid_ctxt = xmlRelaxNGNewValidCtxt(schema);
    if (valid_ctxt == NULL) {
        return Nan::ThrowError("Unable to create a validation context for the RELAX NG schema");
    }
    bool valid = xmlRelaxNGValidateDoc(valid_ctxt, document->xml_obj) == 0;

    xmlSetStructuredErrorFunc(NULL, NULL);
    Nan::Set(info.Holder(), Nan::New<v8::String>("validationErrors").ToLocalChecked(), errors);

    xmlRelaxNGFreeValidCtxt(valid_ctxt);
    xmlRelaxNGFree(schema);
    xmlRelaxNGFreeParserCtxt(parser_ctxt);

    return info.GetReturnValue().Set(Nan::New<v8::Boolean>(valid));
}
NAN_METHOD(XmlDocument::RngValidate)
{
    Nan::HandleScope scope;

    v8::Local<v8::Array> errors = Nan::New<v8::Array>();
    xmlResetLastError();
    xmlSetStructuredErrorFunc(reinterpret_cast<void *>(&errors),
            XmlSyntaxError::PushToArray);

    XmlDocument* document = Nan::ObjectWrap::Unwrap<XmlDocument>(info.Holder());
    XmlDocument* documentSchema = Nan::ObjectWrap::Unwrap<XmlDocument>(Nan::To<v8::Object>(info[0]).ToLocalChecked());

    xmlRelaxNGParserCtxtPtr parser_ctxt = xmlRelaxNGNewDocParserCtxt(documentSchema->xml_obj);
    if (parser_ctxt == NULL) {
        return Nan::ThrowError("Could not create context for RELAX NG schema parser");
    }

    xmlRelaxNGPtr schema = xmlRelaxNGParse(parser_ctxt);
    if (schema == NULL) {
        return Nan::ThrowError("Invalid RELAX NG schema");
    }

    xmlRelaxNGValidCtxtPtr valid_ctxt = xmlRelaxNGNewValidCtxt(schema);
    if (valid_ctxt == NULL) {
        return Nan::ThrowError("Unable to create a validation context for the RELAX NG schema");
    }
    bool valid = xmlRelaxNGValidateDoc(valid_ctxt, document->xml_obj) == 0;

    xmlSetStructuredErrorFunc(NULL, NULL);
    Nan::Set(info.Holder(), Nan::New<v8::String>("validationErrors").ToLocalChecked(), errors);

    xmlRelaxNGFreeValidCtxt(valid_ctxt);
    xmlRelaxNGFree(schema);
    xmlRelaxNGFreeParserCtxt(parser_ctxt);

    return info.GetReturnValue().Set(Nan::New<v8::Boolean>(valid));
}