209 lines
4.3 KiB
C
209 lines
4.3 KiB
C
#include <nokogiri.h>
|
|
|
|
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<name(String)⇒Notation>
|
|
*
|
|
* [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);
|
|
doc = noko_xml_document_unwrap(document);
|
|
error_list = rb_ary_new();
|
|
|
|
ctxt = xmlNewValidCtxt();
|
|
|
|
xmlSetStructuredErrorFunc((void *)error_list, noko__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(void)
|
|
{
|
|
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);
|
|
}
|