class Nokogiri::XML::Schema
Nokogiri::XML::Schema is used for validating XML against an XSD schema definition.
âš Since v1.11.0, Schema treats inputs as untrusted by default, and so external entities are not resolved from the network (http:// or ftp://). When parsing a trusted document, the caller may turn off the NONET option via the ParseOptions to (re-)enable external entity resolution over a network connection.
🛡 Before v1.11.0, documents were “trusted” by default during schema parsing which was counter to Nokogiri’s “untrusted by default” security policy.
Example: Determine whether an XML document is valid.
schema = Nokogiri::XML::Schema.new(File.read(XSD_FILE)) doc = Nokogiri::XML::Document.parse(File.read(XML_FILE)) schema.valid?(doc) # Boolean
Example: Validate an XML document against an XSD schema, and capture any errors that are found.
schema = Nokogiri::XML::Schema.new(File.read(XSD_FILE)) doc = Nokogiri::XML::Document.parse(File.read(XML_FILE)) errors = schema.validate(doc) # Array<SyntaxError>
Example: Validate an XML document using a Document containing an XSD schema definition.
schema_doc = Nokogiri::XML::Document.parse(File.read(RELAX_NG_FILE)) schema = Nokogiri::XML::Schema.from_document(schema_doc) doc = Nokogiri::XML::Document.parse(File.read(XML_FILE)) schema.valid?(doc) # Boolean
Attributes
The errors found while parsing the XSD
- Returns
-
Array<Nokogiri::XML::SyntaxError>
The options used to parse the schema
- Returns
Public Class Methods
Source
static VALUE
noko_xml_schema_s_from_document(int argc, VALUE *argv, VALUE rb_class)
{
/* TODO: deprecate this method and put file-or-string logic into .new so that becomes the
* preferred entry point, and this can become a private method */
VALUE rb_document;
VALUE rb_parse_options;
VALUE rb_schema;
xmlDocPtr c_document;
xmlSchemaParserCtxtPtr c_parser_context;
int defensive_copy_p = 0;
rb_scan_args(argc, argv, "11", &rb_document, &rb_parse_options);
if (!rb_obj_is_kind_of(rb_document, cNokogiriXmlNode)) {
rb_raise(rb_eTypeError,
"expected parameter to be a Nokogiri::XML::Document, received %"PRIsVALUE,
rb_obj_class(rb_document));
}
if (!rb_obj_is_kind_of(rb_document, cNokogiriXmlDocument)) {
xmlNodePtr deprecated_node_type_arg;
NOKO_WARN_DEPRECATION("Passing a Node as the first parameter to Schema.from_document is deprecated. Please pass a Document instead. This will become an error in Nokogiri v1.17.0."); // TODO: deprecated in v1.15.3, remove in v1.17.0
Noko_Node_Get_Struct(rb_document, xmlNode, deprecated_node_type_arg);
c_document = deprecated_node_type_arg->doc;
} else {
c_document = noko_xml_document_unwrap(rb_document);
}
if (noko_xml_document_has_wrapped_blank_nodes_p(c_document)) {
// see https://github.com/sparklemotion/nokogiri/pull/2001
c_document = xmlCopyDoc(c_document, 1);
defensive_copy_p = 1;
}
c_parser_context = xmlSchemaNewDocParserCtxt(c_document);
rb_schema = xml_schema_parse_schema(rb_class, c_parser_context, rb_parse_options);
if (defensive_copy_p) {
xmlFreeDoc(c_document);
c_document = NULL;
}
return rb_schema;
}
Parse an XSD schema definition from a Document to create a new Nokogiri::XML::Schema
- Parameters
-
input(XML::Document) A document containing the XSD schema definition -
parse_options(Nokogiri::XML::ParseOptions) Defaults to Nokogiri::XML::ParseOptions::DEFAULT_SCHEMA
- Returns
Source
# File lib/nokogiri/xml/schema.rb, line 69 def self.new(input, parse_options_ = ParseOptions::DEFAULT_SCHEMA, parse_options: parse_options_) from_document(Nokogiri::XML::Document.parse(input), parse_options) end
Parse an XSD schema definition from a String or IO to create a new Nokogiri::XML::Schema
- Parameters
-
input(String | IO) XSD schema definition -
parse_options(Nokogiri::XML::ParseOptions) Defaults to Nokogiri::XML::ParseOptions::DEFAULT_SCHEMA
- Returns
Source
# File lib/nokogiri/xml/schema.rb, line 78 def self.read_memory(...) # TODO deprecate this method new(...) end
Convenience method for Nokogiri::XML::Schema.new
Public Instance Methods
Source
# File lib/nokogiri/xml/schema.rb, line 135 def valid?(input) validate(input).empty? end
Validate input and return a Boolean indicating whether the document is valid
- Parameters
-
input(Nokogiri::XML::Document| String) A parsed document, or a string containing a local filename.
- Returns
-
Boolean
Example: Validate an existing XML::Document
schema = Nokogiri::XML::Schema.new(File.read(XSD_FILE)) return unless schema.valid?(document)
Example: Validate an XML document on disk
schema = Nokogiri::XML::Schema.new(File.read(XSD_FILE)) return unless schema.valid?("/path/to/file.xml")
Source
# File lib/nokogiri/xml/schema.rb, line 104 def validate(input) if input.is_a?(Nokogiri::XML::Document) validate_document(input) elsif File.file?(input) validate_file(input) else raise ArgumentError, "Must provide Nokogiri::XML::Document or the name of an existing file" end end
Validate input and return any errors that are found.
- Parameters
-
input(Nokogiri::XML::Document| String) A parsed document, or a string containing a local filename.
- Returns
-
Array<SyntaxError>
Example: Validate an existing XML::Document, and capture any errors that are found.
schema = Nokogiri::XML::Schema.new(File.read(XSD_FILE)) errors = schema.validate(document)
Example: Validate an XML document on disk, and capture any errors that are found.
schema = Nokogiri::XML::Schema.new(File.read(XSD_FILE)) errors = schema.validate("/path/to/file.xml")
Private Instance Methods
Source
static VALUE
noko_xml_schema__validate_document(VALUE self, VALUE document)
{
xmlDocPtr doc;
xmlSchemaPtr schema;
xmlSchemaValidCtxtPtr valid_ctxt;
VALUE errors;
TypedData_Get_Struct(self, xmlSchema, &xml_schema_type, schema);
doc = noko_xml_document_unwrap(document);
errors = rb_ary_new();
valid_ctxt = xmlSchemaNewValidCtxt(schema);
if (NULL == valid_ctxt) {
/* we have a problem */
rb_raise(rb_eRuntimeError, "Could not create a validation context");
}
xmlSchemaSetValidStructuredErrors(
valid_ctxt,
noko__error_array_pusher,
(void *)errors
);
int status = xmlSchemaValidateDoc(valid_ctxt, doc);
xmlSchemaFreeValidCtxt(valid_ctxt);
if (status != 0) {
if (RARRAY_LEN(errors) == 0) {
rb_ary_push(errors, rb_str_new2("Could not validate document"));
}
}
return errors;
}
Source
static VALUE
noko_xml_schema__validate_file(VALUE self, VALUE rb_filename)
{
xmlSchemaPtr schema;
xmlSchemaValidCtxtPtr valid_ctxt;
const char *filename ;
VALUE errors;
TypedData_Get_Struct(self, xmlSchema, &xml_schema_type, schema);
filename = (const char *)StringValueCStr(rb_filename) ;
errors = rb_ary_new();
valid_ctxt = xmlSchemaNewValidCtxt(schema);
if (NULL == valid_ctxt) {
/* we have a problem */
rb_raise(rb_eRuntimeError, "Could not create a validation context");
}
xmlSchemaSetValidStructuredErrors(
valid_ctxt,
noko__error_array_pusher,
(void *)errors
);
int status = xmlSchemaValidateFile(valid_ctxt, filename, 0);
xmlSchemaFreeValidCtxt(valid_ctxt);
if (status != 0) {
if (RARRAY_LEN(errors) == 0) {
rb_ary_push(errors, rb_str_new2("Could not validate file."));
}
}
return errors;
}