Class: REXMLUtilityNode

Inherits:
Object show all
Defined in:
lib/extlib/hash.rb

Overview

This is a slighly modified version of the XMLUtilityNode from merb.devjavu.com/projects/merb/ticket/95 ([email protected]) 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.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, attributes = {}) ⇒ REXMLUtilityNode

Returns a new instance of REXMLUtilityNode.



289
290
291
292
293
294
295
296
297
298
# File 'lib/extlib/hash.rb', line 289

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

Instance Attribute Details

#attributesObject

Returns the value of attribute attributes.



270
271
272
# File 'lib/extlib/hash.rb', line 270

def attributes
  @attributes
end

#childrenObject

Returns the value of attribute children.



270
271
272
# File 'lib/extlib/hash.rb', line 270

def children
  @children
end

#nameObject

Returns the value of attribute name.



270
271
272
# File 'lib/extlib/hash.rb', line 270

def name
  @name
end

#typeObject

Returns the value of attribute type.



270
271
272
# File 'lib/extlib/hash.rb', line 270

def type
  @type
end

Instance Method Details

#add_node(node) ⇒ Object



300
301
302
303
# File 'lib/extlib/hash.rb', line 300

def add_node(node)
  @text = true if node.is_a? String
  @children << node
end

#inner_htmlObject

Get the inner_html of the REXML node.



406
407
408
# File 'lib/extlib/hash.rb', line 406

def inner_html
  @children.join
end

#to_hashObject



305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
# File 'lib/extlib/hash.rb', line 305

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_htmlString

Converts the node into a readable HTML node.

Returns:

  • (String)

    The HTML node in text form.



413
414
415
416
# File 'lib/extlib/hash.rb', line 413

def to_html
  attributes.merge!(:type => @type ) if @type
  "<#{name}#{attributes.to_xml_attributes}>#{@nil_element ? '' : inner_html}</#{name}>"
end

#to_sObject



419
420
421
# File 'lib/extlib/hash.rb', line 419

def to_s
  to_html
end

#translate_xml_entities(value) ⇒ #gsub

Convert basic XML entities into their literal values.

Parameters:

  • value (#gsub)

    An XML fragment.

Returns:

  • (#gsub)

    The XML fragment after converting entities.



389
390
391
392
393
394
395
# File 'lib/extlib/hash.rb', line 389

def translate_xml_entities(value)
  value.gsub(/&lt;/,   "<").
        gsub(/&gt;/,   ">").
        gsub(/&quot;/, '"').
        gsub(/&apos;/, "'").
        gsub(/&amp;/,  "&")
end

#typecast_value(value) ⇒ Integer, ...

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.

Typecasts a value based upon its type. For instance, if node has #type == “integer”, #=> 12]}

Parameters:

  • value (String)

    The value that is being typecast.

Returns:

  • (Integer, Boolean, Time, Date, Object)

    The result of typecasting value.



378
379
380
381
382
# File 'lib/extlib/hash.rb', line 378

def typecast_value(value)
  return value unless @type
  proc = self.class.typecasts[@type]
  proc.nil? ? value : proc.call(value)
end

#undasherize_keys(params) ⇒ Object

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



398
399
400
401
402
403
# File 'lib/extlib/hash.rb', line 398

def undasherize_keys(params)
  params.keys.each do |key, value|
    params[key.tr("-", "_")] = params.delete(key)
  end
  params
end