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.



249
250
251
252
253
254
255
256
257
258
# File 'lib/extlib/hash.rb', line 249

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.



230
231
232
# File 'lib/extlib/hash.rb', line 230

def attributes
  @attributes
end

#childrenObject

Returns the value of attribute children.



230
231
232
# File 'lib/extlib/hash.rb', line 230

def children
  @children
end

#nameObject

Returns the value of attribute name.



230
231
232
# File 'lib/extlib/hash.rb', line 230

def name
  @name
end

#typeObject

Returns the value of attribute type.



230
231
232
# File 'lib/extlib/hash.rb', line 230

def type
  @type
end

Instance Method Details

#add_node(node) ⇒ Object



260
261
262
263
# File 'lib/extlib/hash.rb', line 260

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

#inner_htmlObject

Get the inner_html of the REXML node.



366
367
368
# File 'lib/extlib/hash.rb', line 366

def inner_html
  @children.join
end

#to_hashObject



265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
# File 'lib/extlib/hash.rb', line 265

def to_hash
  if @type == "file"
    f = StringIO.new(::Base64.decode64(@children.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.



373
374
375
376
# File 'lib/extlib/hash.rb', line 373

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

#to_sObject



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

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.



349
350
351
352
353
354
355
# File 'lib/extlib/hash.rb', line 349

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:



338
339
340
341
342
# File 'lib/extlib/hash.rb', line 338

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



358
359
360
361
362
363
# File 'lib/extlib/hash.rb', line 358

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