Class: XML_XSI::Schema
- Inherits:
-
Object
- Object
- XML_XSI::Schema
- Defined in:
- lib/validate_xml_xsi.rb
Defined Under Namespace
Classes: DocumentError, ValidationError
Instance Attribute Summary collapse
-
#xsd ⇒ Object
readonly
Returns the value of attribute xsd.
Instance Method Summary collapse
-
#initialize(xml_doc) ⇒ Schema
constructor
A new instance of Schema.
- #validate ⇒ Object
Constructor Details
#initialize(xml_doc) ⇒ Schema
Returns a new instance of Schema.
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/validate_xml_xsi.rb', line 38 def initialize(xml_doc) 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 target_ns_href = nil @document.namespaces.each do |ns_prefix, ns_href| target_ns_href = ns_href if ns_prefix.nil? || ns_prefix.empty? || ns_prefix.eql?('xmlns') end raise DocumentError.new("Unable to determine default (xmlns) namespace!") if target_ns_href.nil? || target_ns_href.empty? ## 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=\"#{target_ns_href}\"\n" \ " version=\"1.0\">\n" ## Include the default xml namespace schemata_by_ns = {} ## Iterate over all the elements and find any xsi:schemaLocation attributes ## and build a hash of all of the namespaces and locations @document.search('//*[@xsi:schemaLocation]').each do |elem| elem['xsi:schemaLocation'].scan(/(\S+)\s+(\S+)/).each do |ns_set| if ns_loc = schemata_by_ns[ns_set.first] unless ns_loc.eql?(ns_set.last) raise DocumentError.new("MISMATCHING namespace: #{ns_set.first} -> #{ns_loc} VS #{ns_set.last}") end else schemata_by_ns[ns_set.first] = ns_set.last end end end schemata_by_ns.each do |ns_href, ns_file| @xsd << (ns_href.eql?(target_ns_href) ? " <xsd:include schemaLocation=\"#{ns_file}\"/>\n" : " <xsd:import namespace=\"#{ns_href}\" schemaLocation=\"#{ns_file}\"/>\n") end @xsd << "</xsd:schema>\n" ## Create the Schema objects @schema = Nokogiri::XML::Schema.new(@xsd) end |
Instance Attribute Details
#xsd ⇒ Object (readonly)
Returns the value of attribute xsd.
37 38 39 |
# File 'lib/validate_xml_xsi.rb', line 37 def xsd @xsd end |
Instance Method Details
#validate ⇒ Object
80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/validate_xml_xsi.rb', line 80 def validate errors = [] @schema.errors.each do |err| errors << ValidationError.new(:XSD, err) end errs = @schema.validate(@document) errs.each do |err| fname = (err.file.nil?) ? @document.filename : err.file errors << ValidationError.new(:XML, err, fname) end errors end |