module DDEX::ERN
Constants
- DEFAULT_CONFIG
- ROOT_ELEMENT
- VERSION_ATTR
Public Class Methods
read(xml, options = nil)
click to toggle source
options ???
# File lib/ddex/ern.rb, line 145 def read(xml, options = nil) options ||= {} raise ArgumentError, "options must be a Hash" unless options.is_a?(Hash) doc = parse(xml, options) ver = options[:version] || find_version(doc) klass = load_version(ver) begin klass.from_xml(doc) rescue NoMethodError => e # Yes, 4 real... this is from ROXML raise unless e.name == :root # It's legit raise XMLLoadError, "XML is not well-formed" # This is a subclass of Exception(!) so we must name it rescue ROXML::RequiredElementMissing => e raise XMLLoadError, "missing required element: #{e}" end end
supported_versions()
click to toggle source
# File lib/ddex/ern.rb, line 135 def supported_versions config.values.map { |cfg| cfg[:version].dup }.sort end
supports?(version)
click to toggle source
# File lib/ddex/ern.rb, line 139 def supports?(version) version = version.to_s.downcase.strip config.any? { |name,cfg| name == version || cfg[:version] == version || cfg[:message_schema_version_id] == version } end
write(object, options = nil)
click to toggle source
# File lib/ddex/ern.rb, line 164 def write(object, options = nil) raise ArgumentError, "not a DDEX object" unless object.is_a?(DDEX::Element) options ||= {} raise ArgumentError, "options must be a Hash" unless options.is_a?(Hash) xmlopts = options.reject { |k, _| k == :schema } node = object.to_xml return node.to_xml(xmlopts) unless object.class.name.demodulize == ROOT_ELEMENT schema = schema_location(object, options[:schema]) if schema node.add_namespace_definition(XML_SCHEMA_INSTANCE_PREFIX, XML_SCHEMA_INSTANCE_NS) node[XML_SCHEMA_INSTANCE_ATTR] = schema end doc = Nokogiri::XML::Document.new doc.root = node doc.to_xml(xmlopts) end
Private Class Methods
find_version(doc)
click to toggle source
# File lib/ddex/ern.rb, line 201 def find_version(doc) return doc.root[VERSION_ATTR] if doc.root[VERSION_ATTR] # Versions >= 4 don't have VERSION_ATTR so we resort to looking at namespaces. # For example, given: http://ddex.net/xml/ern/41 # We'll try to match the end: "ern/41" or "ern/41/" names = doc.collect_namespaces.values version = config.values.find do |cfg| names.any? { |name| name =~ %r|#{ Regexp.quote(cfg[:message_schema_version_id]) }/?\z|i } end return unless version version[:message_schema_version_id] end
load_version(version)
click to toggle source
# File lib/ddex/ern.rb, line 231 def load_version(version) raise_unknown_version(version) if version.nil? # Some normalization v = version.strip.gsub(%r{//+}, "/").gsub(%r{\A/|/\Z}, "") klass, _ = config.find do |name, cfg| cfg[:message_schema_version_id] == v || cfg[:version] == v end raise_unknown_version(version) unless klass # >= 2.0 allows for one call DDEX::ERN.const_get(klass).const_get(ROOT_ELEMENT) rescue LoadError, NameError => e raise_unknown_version(version) end
parse(xml, options)
click to toggle source
# File lib/ddex/ern.rb, line 216 def parse(xml, options) xml = File.read(xml) if xml.is_a?(String) and xml !~ /\A\s*<[?\w]/ Nokogiri::XML(xml, nil, options[:encoding]) { |cfg| cfg.strict } # ArgumentError means there was a problem with types, expected an int, got a str rescue IOError, SystemCallError, ArgumentError => e raise XMLLoadError, "cannot load XML: #{e}" rescue Nokogiri::XML::SyntaxError => e raise XMLLoadError, "XML parsing error: #{e}" end
raise_unknown_version(version)
click to toggle source
# File lib/ddex/ern.rb, line 226 def raise_unknown_version(version) message = "ERN version %s" % (version ? "'#{version}' is unsupported" : "attribute missing") raise UnknownVersionError, message end
schema_location(object, schema)
click to toggle source
# File lib/ddex/ern.rb, line 188 def schema_location(object, schema) # extract version from namespace e.g., DDEX::ERN::V36::NewReleaseMessage ver = object.class.name.split("::")[-2] return unless schema or config.include?(ver) # Check if it's "NS schema" if schema && schema.strip.include?(" ") schema else sprintf "%s %s", object.class.ns[1], schema || config[ver][:schema] end end