Class REXMLUtilityNode
In: lib/extlib/hash.rb
Parent: Object
Hash ToHashParser REXMLUtilityNode dot/f_7.png

This is a slighly modified version of the XMLUtilityNode from merb.devjavu.com/projects/merb/ticket/95 (has.sox@gmail.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.

Methods

Attributes

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

Public Class methods

[Source]

     # File lib/extlib/hash.rb, line 281
281:   def initialize(name, attributes = {})
282:     @name         = name.tr("-", "_")
283:     # leave the type alone if we don't know what it is
284:     @type         = self.class.available_typecasts.include?(attributes["type"]) ? attributes.delete("type") : attributes["type"]
285: 
286:     @nil_element  = attributes.delete("nil") == "true"
287:     @attributes   = undasherize_keys(attributes)
288:     @children     = []
289:     @text         = false
290:   end

Public Instance methods

[Source]

     # File lib/extlib/hash.rb, line 292
292:   def add_node(node)
293:     @text = true if node.is_a? String
294:     @children << node
295:   end

Get the inner_html of the REXML node.

[Source]

     # File lib/extlib/hash.rb, line 398
398:   def inner_html
399:     @children.join
400:   end

[Source]

     # File lib/extlib/hash.rb, line 297
297:   def to_hash
298:     if @type == "file"
299:       f = StringIO.new((@children.first || '').unpack('m').first)
300:       class << f
301:         attr_accessor :original_filename, :content_type
302:       end
303:       f.original_filename = attributes['name'] || 'untitled'
304:       f.content_type = attributes['content_type'] || 'application/octet-stream'
305:       return {name => f}
306:     end
307: 
308:     if @text
309:       return { name => typecast_value( translate_xml_entities( inner_html ) ) }
310:     else
311:       #change repeating groups into an array
312:       groups = @children.inject({}) { |s,e| (s[e.name] ||= []) << e; s }
313: 
314:       out = nil
315:       if @type == "array"
316:         out = []
317:         groups.each do |k, v|
318:           if v.size == 1
319:             out << v.first.to_hash.entries.first.last
320:           else
321:             out << v.map{|e| e.to_hash[k]}
322:           end
323:         end
324:         out = out.flatten
325: 
326:       else # If Hash
327:         out = {}
328:         groups.each do |k,v|
329:           if v.size == 1
330:             out.merge!(v.first)
331:           else
332:             out.merge!( k => v.map{|e| e.to_hash[k]})
333:           end
334:         end
335:         out.merge! attributes unless attributes.empty?
336:         out = out.empty? ? nil : out
337:       end
338: 
339:       if @type && out.nil?
340:         { name => typecast_value(out) }
341:       else
342:         { name => out }
343:       end
344:     end
345:   end

Converts the node into a readable HTML node.

@return <String> The HTML node in text form.

[Source]

     # File lib/extlib/hash.rb, line 405
405:   def to_html
406:     attributes.merge!(:type => @type ) if @type
407:     "<#{name}#{attributes.to_xml_attributes}>#{@nil_element ? '' : inner_html}</#{name}>"
408:   end

@alias to_html to_s

[Source]

     # File lib/extlib/hash.rb, line 411
411:   def to_s
412:     to_html
413:   end

Convert basic XML entities into their literal values.

@param value<gsub> An XML fragment.

@return <gsub> The XML fragment after converting entities.

[Source]

     # File lib/extlib/hash.rb, line 381
381:   def translate_xml_entities(value)
382:     value.gsub(/&lt;/,   "<").
383:           gsub(/&gt;/,   ">").
384:           gsub(/&quot;/, '"').
385:           gsub(/&apos;/, "'").
386:           gsub(/&amp;/,  "&")
387:   end

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, TrueClass, FalseClass, 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.

[Source]

     # File lib/extlib/hash.rb, line 370
370:   def typecast_value(value)
371:     return value unless @type
372:     proc = self.class.typecasts[@type]
373:     proc.nil? ? value : proc.call(value)
374:   end

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

[Source]

     # File lib/extlib/hash.rb, line 390
390:   def undasherize_keys(params)
391:     params.keys.each do |key, value|
392:       params[key.tr("-", "_")] = params.delete(key)
393:     end
394:     params
395:   end

[Validate]