Class: REXMLUtilityNode

Inherits:
Object show all
Defined in:
lib/httparty/parsers/xml.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

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

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

Returns a new instance of REXMLUtilityNode.



45
46
47
48
49
50
51
52
53
54
# File 'lib/httparty/parsers/xml.rb', line 45

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

:nodoc:



11
12
13
# File 'lib/httparty/parsers/xml.rb', line 11

def attributes
  @attributes
end

#childrenObject

:nodoc:



11
12
13
# File 'lib/httparty/parsers/xml.rb', line 11

def children
  @children
end

#nameObject

:nodoc:



11
12
13
# File 'lib/httparty/parsers/xml.rb', line 11

def name
  @name
end

#typeObject

:nodoc:



11
12
13
# File 'lib/httparty/parsers/xml.rb', line 11

def type
  @type
end

Class Method Details

.available_typecastsObject



21
22
23
# File 'lib/httparty/parsers/xml.rb', line 21

def self.available_typecasts
  @@available_typecasts
end

.available_typecasts=(obj) ⇒ Object



25
26
27
# File 'lib/httparty/parsers/xml.rb', line 25

def self.available_typecasts=(obj)
  @@available_typecasts = obj
end

.typecastsObject



13
14
15
# File 'lib/httparty/parsers/xml.rb', line 13

def self.typecasts
  @@typecasts
end

.typecasts=(obj) ⇒ Object



17
18
19
# File 'lib/httparty/parsers/xml.rb', line 17

def self.typecasts=(obj)
  @@typecasts = obj
end

Instance Method Details

#add_node(node) ⇒ Object



56
57
58
59
# File 'lib/httparty/parsers/xml.rb', line 56

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

#inner_htmlObject

Get the inner_html of the REXML node.



162
163
164
# File 'lib/httparty/parsers/xml.rb', line 162

def inner_html
  @children.join
end

#to_hashObject



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/httparty/parsers/xml.rb', line 61

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.



169
170
171
172
# File 'lib/httparty/parsers/xml.rb', line 169

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

#to_sObject



175
176
177
# File 'lib/httparty/parsers/xml.rb', line 175

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.



145
146
147
148
149
150
151
# File 'lib/httparty/parsers/xml.rb', line 145

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:



134
135
136
137
138
# File 'lib/httparty/parsers/xml.rb', line 134

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



154
155
156
157
158
159
# File 'lib/httparty/parsers/xml.rb', line 154

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