class REXMLUtilityNode

This is a slighly modified version of the XMLUtilityNode from merb.devjavu.com/projects/merb/ticket/95 (gmail at has.sox.com) It's mainly just adding vowels, as I ht cd wth n vwls :) This represents the hard part of the work, all I did was change the underlying parser.

Attributes

attributes[RW]
children[RW]
name[RW]
type[RW]

Public Class Methods

new(name, attributes = {}) click to toggle source
# File lib/extlib/hash.rb, line 290
def initialize(name, attributes = {})
  @name         = name.tr("-", "_")
  # leave the type alone if we don't know what it is
  @type         = self.class.available_typecasts.include?(attributes["type"]) ? attributes.delete("type") : attributes["type"]

  @nil_element  = attributes.delete("nil") == "true"
  @attributes   = undasherize_keys(attributes)
  @children     = []
  @text         = false
end

Public Instance Methods

add_node(node) click to toggle source
# File lib/extlib/hash.rb, line 301
def add_node(node)
  @text = true if node.is_a? String
  @children << node
end
inner_html() click to toggle source

Get the #inner_html of the REXML node.

# File lib/extlib/hash.rb, line 407
def inner_html
  @children.join
end
to_hash() click to toggle source
# File lib/extlib/hash.rb, line 306
def to_hash
  if @type == "file"
    f = StringIO.new((@children.first || '').unpack('m').first)
    class << f
      attr_accessor :original_filename, :content_type
    end
    f.original_filename = attributes['name'] || 'untitled'
    f.content_type = attributes['content_type'] || 'application/octet-stream'
    return {name => f}
  end

  if @text
    return { name => typecast_value( translate_xml_entities( inner_html ) ) }
  else
    #change repeating groups into an array
    groups = @children.inject({}) { |s,e| (s[e.name] ||= []) << e; s }

    out = nil
    if @type == "array"
      out = []
      groups.each do |k, v|
        if v.size == 1
          out << v.first.to_hash.entries.first.last
        else
          out << v.map{|e| e.to_hash[k]}
        end
      end
      out = out.flatten

    else # If Hash
      out = {}
      groups.each do |k,v|
        if v.size == 1
          out.merge!(v.first)
        else
          out.merge!( k => v.map{|e| e.to_hash[k]})
        end
      end
      out.merge! attributes unless attributes.empty?
      out = out.empty? ? nil : out
    end

    if @type && out.nil?
      { name => typecast_value(out) }
    else
      { name => out }
    end
  end
end
to_html() click to toggle source

Converts the node into a readable HTML node.

@return [String] The HTML node in text form.

# File lib/extlib/hash.rb, line 414
def to_html
  attributes.merge!(:type => @type ) if @type
  "<#{name}#{attributes.to_xml_attributes}>#{@nil_element ? '' : inner_html}</#{name}>"
end
to_s() click to toggle source

@alias to_html to_s

# File lib/extlib/hash.rb, line 420
def to_s
  to_html
end
translate_xml_entities(value) click to toggle source

Convert basic XML entities into their literal values.

@param value<gsub> An XML fragment.

@return [gsub] The XML fragment after converting entities.

# File lib/extlib/hash.rb, line 390
def translate_xml_entities(value)
  value.gsub(%r&lt;/,   "<").
        gsub(%r&gt;/,   ">").
        gsub(%r&quot;/, '"').
        gsub(%r&apos;/, "'").
        gsub(%r&amp;/,  "&")
end
typecast_value(value) click to toggle source

Typecasts a value based upon its type. For instance, if node has type == "integer", {{[node.typecast_value("12") #=> 12]}}

@param value<String> The value that is being typecast.

@details [:type options]

"integer"::
  converts +value+ to an integer with #to_i
"boolean"::
  checks whether +value+, after removing spaces, is the literal
  "true"
"datetime"::
  Parses +value+ using Time.parse, and returns a UTC Time
"date"::
  Parses +value+ using Date.parse

@return [Integer, Boolean, Time, Date, Object]

The result of typecasting +value+.

@note

If +self+ does not have a "type" key, or if it's not one of the
options specified above, the raw +value+ will be returned.
# File lib/extlib/hash.rb, line 379
def typecast_value(value)
  return value unless @type
  proc = self.class.typecasts[@type]
  proc.nil? ? value : proc.call(value)
end
undasherize_keys(params) click to toggle source

Take keys of the form foo-bar and convert them to foo_bar

# File lib/extlib/hash.rb, line 399
def undasherize_keys(params)
  params.keys.each do |key, value|
    params[key.tr("-", "_")] = params.delete(key)
  end
  params
end