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 Jun 24, 2024
1 parent 73d9f35 commit 25fb309
Show file tree
Hide file tree
Showing 4 changed files with 211 additions and 108 deletions.
46 changes: 30 additions & 16 deletions ext/nokogiri/xml_relax_ng.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,6 @@ static const rb_data_type_t xml_relax_ng_type = {
.flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
};

/*
* call-seq:
* validate_document(document)
*
* Validate a Nokogiri::XML::Document against this RelaxNG schema.
*/
static VALUE
noko_xml_relax_ng__validate_document(VALUE self, VALUE document)
{
Expand Down Expand Up @@ -107,13 +101,23 @@ xml_relax_ng_parse_schema(
}

/*
* call-seq:
* read_memory(string)
* :call-seq:
* read_memory(input) → Nokogiri::XML::RelaxNG
* read_memory(input, parse_options) → Nokogiri::XML::RelaxNG
*
* 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.
*
* Create a new RelaxNG from the contents of +string+
* [Parameters]
* - +input+ (String) RELAX NG schema definition
* - +parse_options+ (Nokogiri::XML::ParseOptions) Defaults to ParseOptions::DEFAULT_SCHEMA
*
* [Returns] Nokogiri::XML::RelaxNG
*/
static VALUE
read_memory(int argc, VALUE *argv, VALUE rb_class)
noko_xml_relax_ng_s_read_memory(int argc, VALUE *argv, VALUE rb_class)
{
VALUE rb_content;
VALUE rb_parse_options;
Expand All @@ -130,13 +134,23 @@ read_memory(int argc, VALUE *argv, VALUE rb_class)
}

/*
* call-seq:
* from_document(doc)
* :call-seq:
* from_document(document) → Nokogiri::XML::RelaxNG
* from_document(document, parse_options) → Nokogiri::XML::RelaxNG
*
* Create a Schema from an already-parsed RELAX NG schema definition document.
*
* [Parameters]
* - +document+ (XML::Document) A XML::Document object representing the parsed RELAX NG
* - +parse_options+ (Nokogiri::XML::ParseOptions) ⚠ Unused
*
* [Returns] Nokogiri::XML::RelaxNG
*
* Create a new RelaxNG schema from the Nokogiri::XML::Document +doc+
* ⚠ +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 rb_class)
noko_xml_relax_ng_s_from_document(int argc, VALUE *argv, VALUE rb_class)
{
VALUE rb_document;
VALUE rb_parse_options;
Expand All @@ -159,8 +173,8 @@ noko_init_xml_relax_ng(void)
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", noko_xml_relax_ng_s_read_memory, -1);
rb_define_singleton_method(cNokogiriXmlRelaxNG, "from_document", noko_xml_relax_ng_s_from_document, -1);

rb_define_private_method(cNokogiriXmlRelaxNG, "validate_document", noko_xml_relax_ng__validate_document, 1);
}
55 changes: 29 additions & 26 deletions ext/nokogiri/xml_schema.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ static const rb_data_type_t xml_schema_type = {
};

static VALUE
validate_document(VALUE self, VALUE document)
noko_xml_schema__validate_document(VALUE self, VALUE document)
{
xmlDocPtr doc;
xmlSchemaPtr schema;
Expand Down Expand Up @@ -50,14 +50,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)
noko_xml_schema__validate_file(VALUE self, VALUE rb_filename)
{
xmlSchemaPtr schema;
xmlSchemaValidCtxtPtr valid_ctxt;
Expand Down Expand Up @@ -96,7 +90,7 @@ xml_schema_parse_schema(
VALUE rb_parse_options
)
{
xmlExternalEntityLoader old_loader = 0;
xmlExternalEntityLoader saved_loader = 0;
libxmlStructuredErrorHandlerState handler_state;

if (NIL_P(rb_parse_options)) {
Expand All @@ -117,14 +111,14 @@ xml_schema_parse_schema(
);

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

xmlSchemaPtr c_schema = xmlSchemaParse(c_parser_context);

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

xmlSchemaFreeParserCtxt(c_parser_context);
Expand All @@ -147,18 +141,24 @@ xml_schema_parse_schema(
}

/*
* call-seq:
* read_memory(string) → Nokogiri::XML::Schema
* :call-seq:
* read_memory(input) → Nokogiri::XML::Schema
* read_memory(input, parse_options) → Nokogiri::XML::Schema
*
* Create a new schema parsed from the contents of +string+
* Parse an XSD schema definition and create a new Schema object.
*
* [Parameters]
* - +string+: String containing XML to be parsed as a schema
* 💡 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.
*
* [parameters]
* - +input+ (String) XSD schema definition
* - +parse_options+ (Nokogiri::XML::ParseOptions)
* Defaults to Nokogiri::XML::ParseOptions::DEFAULT_SCHEMA
*
* [Returns] Nokogiri::XML::Schema
*/
static VALUE
read_memory(int argc, VALUE *argv, VALUE rb_class)
xml_schema_s_read_memory(int argc, VALUE *argv, VALUE rb_class)
{
VALUE rb_content;
VALUE rb_parse_options;
Expand All @@ -175,18 +175,21 @@ read_memory(int argc, VALUE *argv, VALUE rb_class)
}

/*
* call-seq:
* :call-seq:
* from_document(document) → Nokogiri::XML::Schema
* from_document(document, parse_options) → Nokogiri::XML::Schema
*
* Create a new schema parsed from the +document+.
* Create a Schema from an already-parsed XSD schema definition document.
*
* [Parameters]
* - +document+: Nokogiri::XML::Document to be parsed
* - +document+ (XML::Document) A document object representing the parsed XSD
* - +parse_options+ (Nokogiri::XML::ParseOptions)
* Defaults to Nokogiri::XML::ParseOptions::DEFAULT_SCHEMA
*
* [Returns] Nokogiri::XML::Schema
*/
static VALUE
rb_xml_schema_s_from_document(int argc, VALUE *argv, VALUE rb_class)
noko_xml_schema_s_from_document(int argc, VALUE *argv, VALUE rb_class)
{
VALUE rb_document;
VALUE rb_parse_options;
Expand Down Expand Up @@ -236,9 +239,9 @@ noko_init_xml_schema(void)

rb_undef_alloc_func(cNokogiriXmlSchema);

rb_define_singleton_method(cNokogiriXmlSchema, "read_memory", read_memory, -1);
rb_define_singleton_method(cNokogiriXmlSchema, "from_document", rb_xml_schema_s_from_document, -1);
rb_define_singleton_method(cNokogiriXmlSchema, "read_memory", xml_schema_s_read_memory, -1);
rb_define_singleton_method(cNokogiriXmlSchema, "from_document", noko_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", noko_xml_schema__validate_document, 1);
rb_define_private_method(cNokogiriXmlSchema, "validate_file", noko_xml_schema__validate_file, 1);
}
68 changes: 47 additions & 21 deletions lib/nokogiri/xml/relax_ng.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,36 +3,62 @@
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)
# :call-seq:
# RelaxNg(input) → Nokogiri::XML::RelaxNG
# RelaxNg(input, parse_options) → Nokogiri::XML::RelaxNG
#
# Parse a RELAX NG schema definition and create a new Schema object. This is a convenience
# method for Nokogiri::XML::RelaxNG.new
#
# See related: Nokogiri::XML::RelaxNG.new
#
# [Parameters]
# - +input+ (String, IO) RELAX NG schema definition
# - +parse_options+ (Nokogiri::XML::ParseOptions)
# Defaults to ParseOptions::DEFAULT_SCHEMA
#
# [Returns] 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.
#
# Validate an XML document against a RelaxNG schema. Loop over the errors
# that are returned and print them out:
# schema = Nokogiri::XML::RelaxNG(File.read(RELAX_NG_FILE))
# doc = Nokogiri::XML(File.read(XML_FILE))
# schema.valid?(doc) # Boolean
#
# schema = Nokogiri::XML::RelaxNG(File.open(ADDRESS_SCHEMA_FILE))
# doc = Nokogiri::XML(File.open(ADDRESS_XML_FILE))
# *Example:* Validate an XML document against a RelaxNG schema, and capture any errors that are found.
#
# schema.validate(doc).each do |error|
# puts error.message
# end
# schema = Nokogiri::XML::RelaxNG(File.open(RELAX_NG_FILE))
# doc = Nokogiri::XML(File.open(XML_FILE))
# errors = schema.validate(doc) # Array<SyntaxError>
#
# 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.
# ⚠ 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
# :call-seq:
# new(input) → Nokogiri::XML::RelaxNG
# new(input, parse_options) → Nokogiri::XML::RelaxNG
#
# Parse a RELAX NG schema definition and create a new Schema object.
#
# [Parameters]
# - +input+ (String, IO) RELAX NG schema definition
# - +parse_options+ (Nokogiri::XML::ParseOptions)
# Defaults to ParseOptions::DEFAULT_SCHEMA
#
# [Returns] Nokogiri::XML::RelaxNG
#
def self.new(input, parse_options = ParseOptions::DEFAULT_SCHEMA)
from_document(Nokogiri::XML(input), parse_options)
end
end
end
end
Loading

0 comments on commit 25fb309

Please sign in to comment.