#include VALUE cNokogiriXmlDtd; static void notation_copier(void *c_notation_ptr, void *rb_hash_ptr, const xmlChar *name) { VALUE rb_hash = (VALUE)rb_hash_ptr; xmlNotationPtr c_notation = (xmlNotationPtr)c_notation_ptr; VALUE rb_notation; VALUE cNokogiriXmlNotation; VALUE rb_constructor_args[3]; rb_constructor_args[0] = (c_notation->name ? NOKOGIRI_STR_NEW2(c_notation->name) : Qnil); rb_constructor_args[1] = (c_notation->PublicID ? NOKOGIRI_STR_NEW2(c_notation->PublicID) : Qnil); rb_constructor_args[2] = (c_notation->SystemID ? NOKOGIRI_STR_NEW2(c_notation->SystemID) : Qnil); cNokogiriXmlNotation = rb_const_get_at(mNokogiriXml, rb_intern("Notation")); rb_notation = rb_class_new_instance(3, rb_constructor_args, cNokogiriXmlNotation); rb_hash_aset(rb_hash, NOKOGIRI_STR_NEW2(name), rb_notation); } static void element_copier(void *c_node_ptr, void *rb_hash_ptr, const xmlChar *c_name) { VALUE rb_hash = (VALUE)rb_hash_ptr; xmlNodePtr c_node = (xmlNodePtr)c_node_ptr; VALUE rb_node = noko_xml_node_wrap(Qnil, c_node); rb_hash_aset(rb_hash, NOKOGIRI_STR_NEW2(c_name), rb_node); } /* * call-seq: * entities * * Get a hash of the elements for this DTD. */ static VALUE entities(VALUE self) { xmlDtdPtr dtd; VALUE hash; Noko_Node_Get_Struct(self, xmlDtd, dtd); if (!dtd->entities) { return Qnil; } hash = rb_hash_new(); xmlHashScan((xmlHashTablePtr)dtd->entities, element_copier, (void *)hash); return hash; } /* * call-seq: * notations() → Hash * * [Returns] All the notations for this DTD in a Hash of Notation +name+ to Notation. */ static VALUE notations(VALUE self) { xmlDtdPtr dtd; VALUE hash; Noko_Node_Get_Struct(self, xmlDtd, dtd); if (!dtd->notations) { return Qnil; } hash = rb_hash_new(); xmlHashScan((xmlHashTablePtr)dtd->notations, notation_copier, (void *)hash); return hash; } /* * call-seq: * attributes * * Get a hash of the attributes for this DTD. */ static VALUE attributes(VALUE self) { xmlDtdPtr dtd; VALUE hash; Noko_Node_Get_Struct(self, xmlDtd, dtd); hash = rb_hash_new(); if (!dtd->attributes) { return hash; } xmlHashScan((xmlHashTablePtr)dtd->attributes, element_copier, (void *)hash); return hash; } /* * call-seq: * elements * * Get a hash of the elements for this DTD. */ static VALUE elements(VALUE self) { xmlDtdPtr dtd; VALUE hash; Noko_Node_Get_Struct(self, xmlDtd, dtd); if (!dtd->elements) { return Qnil; } hash = rb_hash_new(); xmlHashScan((xmlHashTablePtr)dtd->elements, element_copier, (void *)hash); return hash; } /* * call-seq: * validate(document) * * Validate +document+ returning a list of errors */ static VALUE validate(VALUE self, VALUE document) { xmlDocPtr doc; xmlDtdPtr dtd; xmlValidCtxtPtr ctxt; VALUE error_list; Noko_Node_Get_Struct(self, xmlDtd, dtd); Noko_Node_Get_Struct(document, xmlDoc, doc); error_list = rb_ary_new(); ctxt = xmlNewValidCtxt(); xmlSetStructuredErrorFunc((void *)error_list, Nokogiri_error_array_pusher); xmlValidateDtd(ctxt, doc, dtd); xmlSetStructuredErrorFunc(NULL, NULL); xmlFreeValidCtxt(ctxt); return error_list; } /* * call-seq: * system_id * * Get the System ID for this DTD */ static VALUE system_id(VALUE self) { xmlDtdPtr dtd; Noko_Node_Get_Struct(self, xmlDtd, dtd); if (!dtd->SystemID) { return Qnil; } return NOKOGIRI_STR_NEW2(dtd->SystemID); } /* * call-seq: * external_id * * Get the External ID for this DTD */ static VALUE external_id(VALUE self) { xmlDtdPtr dtd; Noko_Node_Get_Struct(self, xmlDtd, dtd); if (!dtd->ExternalID) { return Qnil; } return NOKOGIRI_STR_NEW2(dtd->ExternalID); } void noko_init_xml_dtd() { assert(cNokogiriXmlNode); /* * Nokogiri::XML::DTD wraps DTD nodes in an XML document */ cNokogiriXmlDtd = rb_define_class_under(mNokogiriXml, "DTD", cNokogiriXmlNode); rb_define_method(cNokogiriXmlDtd, "notations", notations, 0); rb_define_method(cNokogiriXmlDtd, "elements", elements, 0); rb_define_method(cNokogiriXmlDtd, "entities", entities, 0); rb_define_method(cNokogiriXmlDtd, "validate", validate, 1); rb_define_method(cNokogiriXmlDtd, "attributes", attributes, 0); rb_define_method(cNokogiriXmlDtd, "system_id", system_id, 0); rb_define_method(cNokogiriXmlDtd, "external_id", external_id, 0); }