Class: XML_XSI::Schema

Inherits:
Object
  • Object
show all
Defined in:
lib/validate_xml_xsi.rb

Defined Under Namespace

Classes: DocumentError, Erroneous, LocationError, NamespaceError, ValidationError

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(xml_doc, schema_locations = {}) ⇒ Schema

Returns a new instance of Schema.

Raises:

  • (ArgumentError)


102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/validate_xml_xsi.rb', line 102

def initialize(xml_doc, schema_locations = {})
  raise ArgumentError.new("Provided schema locations must be a Hash") unless schema_locations.is_a?(Hash)
  unless xml_doc.is_a?(Nokogiri::XML::Document)
    raise DocumentError.new("invalid Nokogiri::XML::Document - #{xml_doc.class.name}")
  end
  @document = xml_doc
  ## Determine default/top/root namespace
  @ns_href = nil
  @document.namespaces.each do |ns_prefix, ns_href|
    @ns_href = ns_href if ns_prefix.nil? || ns_prefix.empty? || ns_prefix.eql?('xmlns')
  end
  raise NamespaceError.new if @ns_href.nil? || @ns_href.empty?

  ## Determine schema locations found in the source document
  schema_locations.merge!(XML_XSI::find_schema_locations(@document))

  raise LocationError.new if schema_locations.empty?
  raise LocationError.new(@ns_href) unless schema_locations.include?(@ns_href)

  ## Build an all-in-one XSD document that imports all of the separate schema locations
  @xsd = "<?xml version=\"1.0\"?>\n"
  @xsd << "<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n" \
          "            targetNamespace=\"#{@ns_href}\"\n" \
          "            version=\"1.0\">\n"

  ## Minimally we need the target namespace location or we have nothing to include
  @xsi_file = schema_locations.delete(@ns_href)
  @xsd << "  <xsd:include schemaLocation=\"#{@xsi_file}\"/>\n" unless @xsi_file.nil?

  ## Now add imports for the other defined schemaLocations
  schema_locations.each do |ns_href, ns_file|
    @xsd << "  <xsd:import namespace=\"#{ns_href}\" schemaLocation=\"#{ns_file}\"/>\n"
  end
  @xsd << "</xsd:schema>\n"

  ## Create the Schema objects
  begin
    @schema = Nokogiri::XML::Schema.new(@xsd)
  rescue Nokogiri::XML::SyntaxError => ex
    ## Trap the errors so we can finish initialization and then
    ## report the errors in a sane manner
    @schema = Erroneous.new(ex)
  end
end

Instance Attribute Details

#xsd ⇒ Object (readonly)

Returns the value of attribute xsd.



101
102
103
# File 'lib/validate_xml_xsi.rb', line 101

def xsd
  @xsd
end

Instance Method Details

#errors ⇒ Object



147
# File 'lib/validate_xml_xsi.rb', line 147

def errors; @schema.errors; end

#validate ⇒ Object



149
150
151
152
153
154
155
# File 'lib/validate_xml_xsi.rb', line 149

def validate
  errs = @schema.validate(@document)
  errs.map do |err|
    fname = err.file.nil? ? @document.filename : err.file
    ValidationError.new(:XML, err, fname)
  end
end