class Nokogiri::XML::RelaxNG - nokogiri-1.8.0 Documentation

# class Nokogiri::XML::RelaxNG

Nokogiri::XML::RelaxNG is used for validating XML against a RelaxNG schema.

## Synopsis¶ ↑

Validate an XML document against a RelaxNG schema. Loop over the errors that are returned and print them out:

    schema  = Nokogiri::XML::RelaxNG(File.open(ADDRESS_SCHEMA_FILE))
    doc     = Nokogiri::XML(File.open(ADDRESS_XML_FILE))

    schema.validate(doc).each do |error|
      puts error.message
    end

The list of errors are Nokogiri::XML::SyntaxError objects.

### Public Class Methods

from_document(doc) click to toggle source

Create a new RelaxNG schema from the Nokogiri::XML::Document `doc`

    static VALUE from_document(VALUE klass, VALUE document)
    {
      xmlDocPtr doc;
      xmlRelaxNGParserCtxtPtr ctx;
      xmlRelaxNGPtr schema;
      VALUE errors;
      VALUE rb_schema;

      Data_Get_Struct(document, xmlDoc, doc);

      /* In case someone passes us a node. ugh. */
      doc = doc->doc;

      ctx = xmlRelaxNGNewDocParserCtxt(doc);

      errors = rb_ary_new();
      xmlSetStructuredErrorFunc((void *)errors, Nokogiri_error_array_pusher);

    #ifdef HAVE_XMLRELAXNGSETPARSERSTRUCTUREDERRORS
      xmlRelaxNGSetParserStructuredErrors(
        ctx,
        Nokogiri_error_array_pusher,
        (void *)errors
      );
    #endif

      schema = xmlRelaxNGParse(ctx);

      xmlSetStructuredErrorFunc(NULL, NULL);

      if(NULL == schema) {
        xmlErrorPtr error = xmlGetLastError();
        if(error)
          Nokogiri_error_raise(NULL, error);
        else
          rb_raise(rb_eRuntimeError, "Could not parse document");

        return Qnil;
      }

      rb_schema = Data_Wrap_Struct(klass, 0, dealloc, schema);
      rb_iv_set(rb_schema, "@errors", errors);

      return rb_schema;
    }

read_memory(string) click to toggle source

Create a new RelaxNG from the contents of `string`

    static VALUE read_memory(VALUE klass, VALUE content)
    {
      xmlRelaxNGParserCtxtPtr ctx = xmlRelaxNGNewMemParserCtxt(
          (const char *)StringValuePtr(content),
          (int)RSTRING_LEN(content)
      );
      xmlRelaxNGPtr schema;
      VALUE errors = rb_ary_new();
      VALUE rb_schema;

      xmlSetStructuredErrorFunc((void *)errors, Nokogiri_error_array_pusher);

    #ifdef HAVE_XMLRELAXNGSETPARSERSTRUCTUREDERRORS
      xmlRelaxNGSetParserStructuredErrors(
        ctx,
        Nokogiri_error_array_pusher,
        (void *)errors
      );
    #endif

      schema = xmlRelaxNGParse(ctx);

      xmlSetStructuredErrorFunc(NULL, NULL);
      xmlRelaxNGFreeParserCtxt(ctx);

      if(NULL == schema) {
        xmlErrorPtr error = xmlGetLastError();
        if(error)
          Nokogiri_error_raise(NULL, error);
        else
          rb_raise(rb_eRuntimeError, "Could not parse document");

        return Qnil;
      }

      rb_schema = Data_Wrap_Struct(klass, 0, dealloc, schema);
      rb_iv_set(rb_schema, "@errors", errors);

      return rb_schema;
    }

### Private Instance Methods

validate_document(document) click to toggle source

Validate a Nokogiri::XML::Document against this RelaxNG schema.

    static VALUE validate_document(VALUE self, VALUE document)
    {
      xmlDocPtr doc;
      xmlRelaxNGPtr schema;
      VALUE errors;
      xmlRelaxNGValidCtxtPtr valid_ctxt;

      Data_Get_Struct(self, xmlRelaxNG, schema);
      Data_Get_Struct(document, xmlDoc, doc);

      errors = rb_ary_new();

      valid_ctxt = xmlRelaxNGNewValidCtxt(schema);

      if(NULL == valid_ctxt) {
        /* we have a problem */
        rb_raise(rb_eRuntimeError, "Could not create a validation context");
      }

    #ifdef HAVE_XMLRELAXNGSETVALIDSTRUCTUREDERRORS
      xmlRelaxNGSetValidStructuredErrors(
        valid_ctxt,
        Nokogiri_error_array_pusher,
        (void *)errors
      );
    #endif

      xmlRelaxNGValidateDoc(valid_ctxt, doc);

      xmlRelaxNGFreeValidCtxt(valid_ctxt);

      return errors;
    }