class Hash
This Hash
extension is needed by old pas3 engines. It’s not automatically loaded. copy the line below on top of the file where from_xml
is needed
require ‘refx/engine/p3lib/p3lib_hash_from_xml’
Constants
- XML_PARSING
Public Class Methods
from_xml(xml, preserve_attributes = false)
click to toggle source
# File lib/refx/engine/p3lib/p3lib_hash_from_xml.rb, line 40 def self.from_xml(xml, preserve_attributes = false) typecast_xml_value(self.undasherize_keys(XmlSimple.xml_in(xml,'forcearray'=>false,'forcecontent'=>true,'keeproot'=>true,'contentkey'=>'__content__')), preserve_attributes) end
Private Class Methods
typecast_xml_value(value, preserve_attributes = false)
click to toggle source
# File lib/refx/engine/p3lib/p3lib_hash_from_xml.rb, line 60 def self.typecast_xml_value(value, preserve_attributes = false) case value.class.to_s when 'Hash' if value['type'] == 'array' #child_key, entries = value.detect { |k,v| k != 'type' } # child_key is throwaway if entries.nil? || (c = value['__content__'] && c.nil?) || (c = value['__content__'] && c.empty?) [] else case entries.class.to_s # something weird with classes not matching here. maybe singleton methods breaking is_a? when "Array" entries.collect { |v| typecast_xml_value(v, preserve_attributes) } when "Hash" [typecast_xml_value(entries, preserve_attributes)] else raise "can't typecast #{entries.inspect}" end end elsif value.has_key?("__content__") content = value["__content__"] if parser = XML_PARSING[value["type"]] if parser.arity == 2 XML_PARSING[value["type"]].call(content, value) else XML_PARSING[value["type"]].call(content) end elsif preserve_attributes && value.keys.size > 1 value["content"] = value.delete("__content__") value else content end elsif value['type'] == 'string' && value['nil'] != 'true' "" # blank or nil parsed values are represented by nil elsif value.nil? || value.empty? || value['nil'] == 'true' nil # If the type is the only element which makes it then # this still makes the value nil, except if type is # a XML node(where type['value'] is a Hash) elsif value['type'] && value.size == 1 && !value['type'].is_a?(::Hash) nil else xml_value = value.inject({}) do |h,(k,v)| h[k] = typecast_xml_value(v, preserve_attributes) h end # Turn { :files => { :file => #<StringIO> } into { :files => #<StringIO> } so it is compatible with # how multipart uploaded files from HTML appear xml_value["file"].is_a?(StringIO) ? xml_value["file"] : xml_value end when 'Array' value.map! { |i| typecast_xml_value(i, preserve_attributes) } case value.length when 0 then nil when 1 then value.first else value end when 'String' value else raise "can't typecast #{value.class.name} - #{value.inspect}" end end
undasherize_keys(params)
click to toggle source
# File lib/refx/engine/p3lib/p3lib_hash_from_xml.rb, line 46 def self.undasherize_keys(params) case params.class.to_s when "Hash" params.inject({}) do |h,(k,v)| h[k.to_s.tr("-", "_")] = self.undasherize_keys(v) h end when "Array" params.map { |v| self.undasherize_keys(v) } else params end end