Skip to content

Commit

Permalink
doc: improve documentation for XML::{Schema,RelaxNG}
Browse files Browse the repository at this point in the history
  • Loading branch information
flavorjones committed Aug 24, 2021
1 parent 5c8dfd9 commit 193d506
Show file tree
Hide file tree
Showing 4 changed files with 152 additions and 117 deletions.
45 changes: 27 additions & 18 deletions ext/nokogiri/xml_relax_ng.c
Expand Up @@ -10,14 +10,9 @@ dealloc(xmlRelaxNGPtr schema)
NOKOGIRI_DEBUG_END(schema);
}

/*
* call-seq:
* validate_document(document)
*
* Validate a Nokogiri::XML::Document against this RelaxNG schema.
*/

static VALUE
validate_document(VALUE self, VALUE document)
rb_xml_relax_ng_validate_document(VALUE self, VALUE document)
{
xmlDocPtr doc;
xmlRelaxNGPtr schema;
Expand Down Expand Up @@ -51,14 +46,21 @@ validate_document(VALUE self, VALUE document)
return errors;
}


/*
* call-seq:
* read_memory(string)
* @overload read_memory(input, parse_options = ParseOptions::DEFAULT_SCHEMA)
*
* Create a new RelaxNG from the contents of +string+
* Parse a RELAX NG schema definition and create a new Schema object.
*
* Note that the limitation of this method relative to {RelaxNG.new} is that +input+ must be type
* String, whereas {RelaxNG.new} also supports IO types.
*
* @param input [String] RELAX NG schema definition
* @param parse_options [Nokogiri::XML::ParseOptions]
* @return [Nokogiri::XML::RelaxNG]
*/
static VALUE
read_memory(int argc, VALUE *argv, VALUE klass)
rb_xml_relax_ng_s_read_memory(int argc, VALUE *argv, VALUE klass)
{
VALUE content;
VALUE parse_options;
Expand Down Expand Up @@ -109,14 +111,21 @@ read_memory(int argc, VALUE *argv, VALUE klass)
return rb_schema;
}


/*
* call-seq:
* from_document(doc)
* @overload from_document(document, parse_options = ParseOptions::DEFAULT_SCHEMA)
*
* Create a Schema from an already-parsed RELAX NG schema definition document.
*
* @param document [XML::Document] A {XML::Document} object representing the parsed RELAX NG
* @param parse_options [Nokogiri::XML::ParseOptions]
* @return [Nokogiri::XML::RelaxNG]
*
* Create a new RelaxNG schema from the Nokogiri::XML::Document +doc+
* @note +parse_options+ is currently unused by this method and is present only as a placeholder
* for future functionality.
*/
static VALUE
from_document(int argc, VALUE *argv, VALUE klass)
rb_xml_relax_ng_s_from_document(int argc, VALUE *argv, VALUE klass)
{
VALUE document;
VALUE parse_options;
Expand Down Expand Up @@ -178,8 +187,8 @@ noko_init_xml_relax_ng()
assert(cNokogiriXmlSchema);
cNokogiriXmlRelaxNG = rb_define_class_under(mNokogiriXml, "RelaxNG", cNokogiriXmlSchema);

rb_define_singleton_method(cNokogiriXmlRelaxNG, "read_memory", read_memory, -1);
rb_define_singleton_method(cNokogiriXmlRelaxNG, "from_document", from_document, -1);
rb_define_singleton_method(cNokogiriXmlRelaxNG, "read_memory", rb_xml_relax_ng_s_read_memory, -1);
rb_define_singleton_method(cNokogiriXmlRelaxNG, "from_document", rb_xml_relax_ng_s_from_document, -1);

rb_define_private_method(cNokogiriXmlRelaxNG, "validate_document", validate_document, 1);
rb_define_private_method(cNokogiriXmlRelaxNG, "validate_document", rb_xml_relax_ng_validate_document, 1);
}
60 changes: 30 additions & 30 deletions ext/nokogiri/xml_schema.c
Expand Up @@ -10,14 +10,8 @@ dealloc(xmlSchemaPtr schema)
NOKOGIRI_DEBUG_END(schema);
}

/*
* call-seq:
* validate_document(document)
*
* Validate a Nokogiri::XML::Document against this Schema.
*/
static VALUE
validate_document(VALUE self, VALUE document)
rb_xml_schema_validate_document(VALUE self, VALUE document)
{
xmlDocPtr doc;
xmlSchemaPtr schema;
Expand Down Expand Up @@ -51,14 +45,8 @@ validate_document(VALUE self, VALUE document)
return errors;
}

/*
* call-seq:
* validate_file(filename)
*
* Validate a file against this Schema.
*/
static VALUE
validate_file(VALUE self, VALUE rb_filename)
rb_xml_schema_validate_file(VALUE self, VALUE rb_filename)
{
xmlSchemaPtr schema;
xmlSchemaValidCtxtPtr valid_ctxt;
Expand Down Expand Up @@ -93,13 +81,19 @@ validate_file(VALUE self, VALUE rb_filename)
}

/*
* call-seq:
* read_memory(string)
* @overload read_memory(input, parse_options = ParseOptions::DEFAULT_SCHEMA)
*
* Parse an XSD schema definition and create a new Schema object.
*
* Note that the limitation of this method relative to {Schema.new} is that +input+ must be type
* String, whereas {Schema.new} also supports IO types.
*
* Create a new Schema from the contents of +string+
* @param input [String] XSD schema definition
* @param parse_options [Nokogiri::XML::ParseOptions]
* @return [Nokogiri::XML::Schema]
*/
static VALUE
read_memory(int argc, VALUE *argv, VALUE klass)
rb_xml_schema_s_read_memory(int argc, VALUE *argv, VALUE klass)
{
VALUE content;
VALUE parse_options;
Expand Down Expand Up @@ -162,6 +156,7 @@ read_memory(int argc, VALUE *argv, VALUE klass)
return rb_schema;
}


/* Schema creation will remove and deallocate "blank" nodes.
* If those blank nodes have been exposed to Ruby, they could get freed
* out from under the VALUE pointer. This function checks to see if any of
Expand All @@ -188,14 +183,18 @@ has_blank_nodes_p(VALUE cache)
return 0;
}


/*
* call-seq:
* from_document(doc)
* @overload from_document(document, parse_options = ParseOptions::DEFAULT_SCHEMA)
*
* Create a new Schema from the Nokogiri::XML::Document +doc+
* Create a Schema from an already-parsed XSD schema definition document.
*
* @param document [XML::Document] A {XML::Document} object representing the parsed XSD
* @param parse_options [Nokogiri::XML::ParseOptions]
* @return [Nokogiri::XML::Schema]
*/
static VALUE
from_document(int argc, VALUE *argv, VALUE klass)
rb_xml_schema_s_from_document(int argc, VALUE *argv, VALUE klass)
{
VALUE document;
VALUE parse_options;
Expand All @@ -206,7 +205,7 @@ from_document(int argc, VALUE *argv, VALUE klass)
VALUE errors;
VALUE rb_schema;
int scanned_args = 0;
xmlExternalEntityLoader old_loader = 0;
xmlExternalEntityLoader saved_loader = 0;

scanned_args = rb_scan_args(argc, argv, "11", &document, &parse_options);

Expand Down Expand Up @@ -236,14 +235,14 @@ from_document(int argc, VALUE *argv, VALUE klass)
#endif

if (parse_options_int & XML_PARSE_NONET) {
old_loader = xmlGetExternalEntityLoader();
saved_loader = xmlGetExternalEntityLoader();
xmlSetExternalEntityLoader(xmlNoNetExternalEntityLoader);
}

schema = xmlSchemaParse(ctx);

if (old_loader) {
xmlSetExternalEntityLoader(old_loader);
if (saved_loader) {
xmlSetExternalEntityLoader(saved_loader);
}

xmlSetStructuredErrorFunc(NULL, NULL);
Expand All @@ -269,16 +268,17 @@ from_document(int argc, VALUE *argv, VALUE klass)
return Qnil;
}


void
noko_init_xml_schema()
{
cNokogiriXmlSchema = rb_define_class_under(mNokogiriXml, "Schema", rb_cObject);

rb_undef_alloc_func(cNokogiriXmlSchema);

rb_define_singleton_method(cNokogiriXmlSchema, "read_memory", read_memory, -1);
rb_define_singleton_method(cNokogiriXmlSchema, "from_document", from_document, -1);
rb_define_singleton_method(cNokogiriXmlSchema, "read_memory", rb_xml_schema_s_read_memory, -1);
rb_define_singleton_method(cNokogiriXmlSchema, "from_document", rb_xml_schema_s_from_document, -1);

rb_define_private_method(cNokogiriXmlSchema, "validate_document", validate_document, 1);
rb_define_private_method(cNokogiriXmlSchema, "validate_file", validate_file, 1);
rb_define_private_method(cNokogiriXmlSchema, "validate_document", rb_xml_schema_validate_document, 1);
rb_define_private_method(cNokogiriXmlSchema, "validate_file", rb_xml_schema_validate_file, 1);
}
52 changes: 30 additions & 22 deletions lib/nokogiri/xml/relax_ng.rb
Expand Up @@ -2,36 +2,44 @@
module Nokogiri
module XML
class << self
###
# Create a new Nokogiri::XML::RelaxNG document from +string_or_io+.
# See Nokogiri::XML::RelaxNG for an example.
def RelaxNG(string_or_io, options = ParseOptions::DEFAULT_SCHEMA)
RelaxNG.new(string_or_io, options)
# Parse a RELAX NG schema definition and create a new {Schema} object. This is a convenience
# method for {Nokogiri::XML::RelaxNG.new}.
# @see Nokogiri::XML::RelaxNG.new
#
# @param input [String, IO] RELAX NG schema definition
# @param parse_options [Nokogiri::XML::ParseOptions]
# @return [Nokogiri::XML::RelaxNG]
def RelaxNG(input, parse_options = ParseOptions::DEFAULT_SCHEMA)
RelaxNG.new(input, parse_options)
end
end

###
# Nokogiri::XML::RelaxNG is used for validating XML against a
# RelaxNG schema.
# Nokogiri::XML::RelaxNG is used for validating XML against a RELAX NG schema definition.
#
# == Synopsis
# @example Determine whether an XML document is valid.
# schema = Nokogiri::XML::RelaxNG(File.read(RELAX_NG_FILE))
# doc = Nokogiri::XML(File.read(XML_FILE))
# schema.valid?(doc) # Boolean
#
# Validate an XML document against a RelaxNG schema. Loop over the errors
# that are returned and print them out:
# @example Validate an XML document against a RelaxNG schema, and capture any errors that are found.
# schema = Nokogiri::XML::RelaxNG(File.open(RELAX_NG_FILE))
# doc = Nokogiri::XML(File.open(XML_FILE))
# errors = schema.validate(doc) # Array<SyntaxError>
#
# 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.
#
# NOTE: RelaxNG input is always treated as TRUSTED documents, meaning that they will cause the
# underlying parsing libraries to access network resources. This is counter to Nokogiri's
# "untrusted by default" security policy, but is a limitation of the underlying libraries.
# @note RELAX NG input is always treated as *trusted*, meaning that the underlying parsing
# libraries *will access network resources*. This is counter to Nokogiri's "untrusted by
# default" security policy, but is an unfortunate limitation of the underlying
# libraries. Please do not use this class for untrusted schema documents.
class RelaxNG < Nokogiri::XML::Schema
# Parse a RELAX NG schema definition and create a new {Schema} object.
#
# @param input [String, IO] RELAX NG schema definition
# @param parse_options [Nokogiri::XML::ParseOptions]
# @return [Nokogiri::XML::RelaxNG]
def self.new(input, parse_options = ParseOptions::DEFAULT_SCHEMA)
from_document(Nokogiri::XML(input), parse_options)
end
end
end
end

0 comments on commit 193d506

Please sign in to comment.