/* * call-seq: * from_document(doc) * * 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(); Nokogiri_install_error_catcher(errors); #ifdef HAVE_XMLRELAXNGSETPARSERSTRUCTUREDERRORS xmlRelaxNGSetParserStructuredErrors( ctx, Nokogiri_error_array_pusher, (void *)errors ); #endif schema = xmlRelaxNGParse(ctx); Nokogiri_remove_error_catcher(); 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; }
/* * call-seq: * from_document(doc) * * Create a new Schema from the Nokogiri::XML::Document +doc+ */ static VALUE from_document(VALUE klass, VALUE document) { xmlDocPtr doc; Data_Get_Struct(document, xmlDoc, doc); // In case someone passes us a node. ugh. doc = doc->doc; xmlSchemaParserCtxtPtr ctx = xmlSchemaNewDocParserCtxt(doc); VALUE errors = rb_ary_new(); xmlSetStructuredErrorFunc((void *)errors, Nokogiri_error_array_pusher); #ifdef HAVE_XMLSCHEMASETPARSERSTRUCTUREDERRORS xmlSchemaSetParserStructuredErrors( ctx, Nokogiri_error_array_pusher, (void *)errors ); #endif xmlSchemaPtr schema = xmlSchemaParse(ctx); xmlSetStructuredErrorFunc(NULL, NULL); xmlSchemaFreeParserCtxt(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; } VALUE rb_schema = Data_Wrap_Struct(klass, 0, dealloc, schema); rb_iv_set(rb_schema, "@errors", errors); return rb_schema; return Qnil; }
/* * call-seq: * read_memory(string) * * 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; Nokogiri_install_error_catcher(errors); #ifdef HAVE_XMLRELAXNGSETPARSERSTRUCTUREDERRORS xmlRelaxNGSetParserStructuredErrors( ctx, Nokogiri_error_array_pusher, (void *)errors ); #endif schema = xmlRelaxNGParse(ctx); Nokogiri_remove_error_catcher(); 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; }
/* * call-seq: * native_write(chunk, last_chunk) * * Write +chunk+ to PushParser. +last_chunk+ triggers the end_document handle */ static VALUE native_write(VALUE self, VALUE _chunk, VALUE _last_chunk) { xmlParserCtxtPtr ctx; Data_Get_Struct(self, xmlParserCtxt, ctx); const char * chunk = NULL; int size = 0; if(Qnil != _chunk) { chunk = StringValuePtr(_chunk); size = RSTRING_LEN(_chunk); } if(xmlParseChunk(ctx, chunk, size, Qtrue == _last_chunk ? 1 : 0)) { if (!(ctx->options & XML_PARSE_RECOVER)) { xmlErrorPtr e = xmlCtxtGetLastError(ctx); Nokogiri_error_raise(NULL, e); } } return self; }