class Nokogiri::XML::Schema

def self.from_document document

def self.from_document document
  ctx = LibXML.xmlSchemaNewDocParserCtxt(document.document.cstruct)
  errors = []
  LibXML.xmlSetStructuredErrorFunc(nil, SyntaxError.error_array_pusher(errors))
  unless Nokogiri.is_2_6_16?
    LibXML.xmlSchemaSetParserStructuredErrors(
      ctx,
      SyntaxError.error_array_pusher(errors),
      nil
    )
  end
  schema_ptr = LibXML.xmlSchemaParse(ctx)
  LibXML.xmlSetStructuredErrorFunc(nil, nil)
  LibXML.xmlSchemaFreeParserCtxt(ctx)
  if schema_ptr.null?
    error = LibXML.xmlGetLastError
    if error
      raise SyntaxError.wrap(error)
    else
      raise RuntimeError, "Could not parse document"
    end
  end
  schema = allocate
  schema.cstruct = LibXML::XmlSchema.new schema_ptr
  schema.errors = errors
  schema
end

def self.new string_or_io

object.
Create a new Nokogiri::XML::Schema object using a +string_or_io+
##
def self.new string_or_io
  from_document Nokogiri::XML(string_or_io)
end

def self.read_memory content

def self.read_memory content
  content_copy = FFI::MemoryPointer.from_string(content)
  ctx = LibXML.xmlSchemaNewMemParserCtxt(content_copy, content.length)
  errors = []
  LibXML.xmlSetStructuredErrorFunc(nil, SyntaxError.error_array_pusher(errors))
  LibXML.xmlSchemaSetParserStructuredErrors(ctx, SyntaxError.error_array_pusher(errors), nil) unless Nokogiri.is_2_6_16?
  schema_ptr = LibXML.xmlSchemaParse(ctx)
  LibXML.xmlSetStructuredErrorFunc(nil, nil)
  LibXML.xmlSchemaFreeParserCtxt(ctx)
  if schema_ptr.null?
    error = LibXML.xmlGetLastError
    if error
      raise SyntaxError.wrap(error)
    else
      raise RuntimeError, "Could not parse document"
    end
  end
  schema = allocate
  schema.cstruct = LibXML::XmlSchema.new schema_ptr
  schema.errors = errors
  schema
end

def valid? thing

file.
Returns true if +thing+ is a valid Nokogiri::XML::Document or
##
def valid? thing
  validate(thing).length == 0
end

def validate thing

+thing+ is returned.
Nokogiri::XML::SyntaxError objects found while validating the
Nokogiri::XML::Document object, or a filename. An Array of
Validate +thing+ against this schema. +thing+ can be a
##
def validate thing
  return validate_document(thing) if thing.is_a?(Nokogiri::XML::Document)
  # FIXME libxml2 has an api for validating files.  We should switch
  # to that because it will probably save memory.
  validate_document(Nokogiri::XML(File.read(thing)))
end

def validate_document document

def validate_document document
  errors = []
  ctx = LibXML.xmlSchemaNewValidCtxt(cstruct)
  raise RuntimeError.new("Could not create a validation context") if ctx.null?
  LibXML.xmlSchemaSetValidStructuredErrors(ctx,
    SyntaxError.error_array_pusher(errors), nil) unless Nokogiri.is_2_6_16?
  LibXML.xmlSchemaValidateDoc(ctx, document.cstruct)
  LibXML.xmlSchemaFreeValidCtxt(ctx)
  errors
end