Class: Nori::XMLUtilityNode

Inherits:
Object
  • Object
show all
Defined in:
lib/nori/xml_utility_node.rb

Overview

This is a slighly modified version of the XMLUtilityNode from http://merb.devjavu.com/projects/merb/ticket/95 (has.sox@gmail.com)

John Nunemaker: 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.

Constant Summary collapse

XS_TIME =

Simple xs:time Regexp. Valid xs:time formats 13:20:00 1:20 PM 13:20:30.5555 1:20 PM and 30.5555 seconds 13:20:00-05:00 1:20 PM, US Eastern Standard Time 13:20:00+02:00 1:20 PM, Central European Standard Time 13:20:00Z 1:20 PM, Coordinated Universal Time (UTC) 13:20:30.5555Z 1:20 PM and 30.5555 seconds, Coordinated Universal Time (UTC) 00:00:00 midnight 24:00:00 midnight

/^\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:?\d{2})?$/
XS_DATE =

Simple xs:date Regexp. Valid xs:date formats 2004-04-12 April 12, 2004 -0045-01-01 January 1, 45 BC 12004-04-12 April 12, 12004 2004-04-12-05:00 April 12, 2004, US Eastern Standard Time, which is 5 hours behind Coordinated Universal Time (UTC) 2004-04-12+02:00 April 12, 2004, Central European Summer Time, which is 2 hours ahead of Coordinated Universal Time (UTC) 2004-04-12Z April 12, 2004, Coordinated Universal Time (UTC)

/^-?\d{4}-\d{2}-\d{2}(?:Z|[+-]\d{2}:?\d{2})?$/
XS_DATE_TIME =

Simple xs:dateTime Regexp. Valid xs:dateTime formats 2004-04-12T13:20:00 1:20 pm on April 12, 2004 2004-04-12T13:20:15.5 1:20 pm and 15.5 seconds on April 12, 2004 2004-04-12T13:20:00-05:00 1:20 pm on April 12, 2004, US Eastern Standard Time 2004-04-12T13:20:00+02:00 1:20 pm on April 12, 2004, Central European Summer Time 2004-04-12T13:20:15.5-05:00 1:20 pm and 15.5 seconds on April 12, 2004, US Eastern Standard Time 2004-04-12T13:20:00Z 1:20 pm on April 12, 2004, Coordinated Universal Time (UTC) 2004-04-12T13:20:15.5Z 1:20 pm and 15.5 seconds on April 12, 2004, Coordinated Universal Time (UTC)

/^-?\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:?\d{2})?$/

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options, name, attributes = {}) ⇒ XMLUtilityNode

Returns a new instance of XMLUtilityNode.



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/nori/xml_utility_node.rb', line 86

def initialize(options, name, attributes = {})
  @options = options
  @name = Nori.hash_key(name, options)

  if converter = options[:convert_attributes_to]
    intermediate = attributes.map {|k, v| converter.call(k, v) }.flatten
    attributes = Hash[*intermediate]
  end

  @type = bare_type(attributes)

  @nil_element = false
  attributes.keys.each do |key|
    if result = nil_attribute_pattern.match(key)
      @nil_element = attributes.delete(key) == "true"
      attributes.delete("xmlns:#{result[2]}") if result[1]
    end
    attributes.delete(key) if @options[:delete_namespace_attributes] && key[/^(xmlns|xsi)/]
  end
  @attributes = undasherize_keys(attributes)
  @children = []
  @text = false
end

Instance Attribute Details

#attributesObject

Returns the value of attribute attributes.



110
111
112
# File 'lib/nori/xml_utility_node.rb', line 110

def attributes
  @attributes
end

#childrenObject

Returns the value of attribute children.



110
111
112
# File 'lib/nori/xml_utility_node.rb', line 110

def children
  @children
end

#nameObject

Returns the value of attribute name.



110
111
112
# File 'lib/nori/xml_utility_node.rb', line 110

def name
  @name
end

#typeObject

Returns the value of attribute type.



110
111
112
# File 'lib/nori/xml_utility_node.rb', line 110

def type
  @type
end

Class Method Details

.available_typecastsObject



64
65
66
# File 'lib/nori/xml_utility_node.rb', line 64

def self.available_typecasts
  @@available_typecasts
end

.available_typecasts=(obj) ⇒ Object



68
69
70
# File 'lib/nori/xml_utility_node.rb', line 68

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

.typecastsObject



56
57
58
# File 'lib/nori/xml_utility_node.rb', line 56

def self.typecasts
  @@typecasts
end

.typecasts=(obj) ⇒ Object



60
61
62
# File 'lib/nori/xml_utility_node.rb', line 60

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

Instance Method Details

#add_node(node) ⇒ Object



124
125
126
127
# File 'lib/nori/xml_utility_node.rb', line 124

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

#advanced_typecasting(value) ⇒ Object



180
181
182
183
184
185
186
187
188
189
190
191
192
# File 'lib/nori/xml_utility_node.rb', line 180

def advanced_typecasting(value)
  split = value.split
  return value if split.size > 1

  case split.first
    when "true"       then true
    when "false"      then false
    when XS_DATE_TIME then try_to_convert(value) {|x| DateTime.parse(x)}
    when XS_DATE      then try_to_convert(value) {|x| Date.parse(x)}
    when XS_TIME      then try_to_convert(value) {|x| Time.parse(x)}
    else                   value
  end
end

#inner_htmlObject

Get the inner_html of the REXML node.



203
204
205
# File 'lib/nori/xml_utility_node.rb', line 203

def inner_html
  @children.join
end

#prefixed_attribute_name(attribute) ⇒ Object



119
120
121
122
# File 'lib/nori/xml_utility_node.rb', line 119

def prefixed_attribute_name(attribute)
  return attribute unless @options[:convert_tags_to].respond_to? :call
  @options[:convert_tags_to].call(attribute)
end

#prefixed_attributesObject



112
113
114
115
116
117
# File 'lib/nori/xml_utility_node.rb', line 112

def prefixed_attributes
  attributes.inject({}) do |memo, (key, value)|
    memo[prefixed_attribute_name("@#{key}")] = value
    memo
  end
end

#to_hashHash{String => Object}

Converts the node into a hash with the node name as its single key.

The value depends on the shape of the node. A node typed as "file" becomes a StringIOFile, unless the :serializable profile is enabled. That profile returns plain data only, so a file node folds into text and attributes like any other node and the base64 content is left undecoded. A node with text content becomes a typecast scalar. Every other node folds its children into an array or a hash. Under the :standards profile no bare type attribute is honored (#bare_type), so file decoding, array folding and typecasting never happen there.

Returns:

  • (Hash{String => Object})

    the node name mapped to its value



141
142
143
144
145
146
147
148
149
# File 'lib/nori/xml_utility_node.rb', line 141

def to_hash
  return { name => file_value } if @type == "file" && !@options[:serializable]
  return { name => text_value } if @text

  groups = group_children
  value = @type == "array" ? array_value(groups) : hash_value(groups)
  value = typecast_value(value) if @type && value.nil?
  { name => value }
end

#to_htmlString Also known as: to_s

Converts the node into a readable HTML node.

Returns:

  • (String)

    The HTML node in text form.



210
211
212
213
# File 'lib/nori/xml_utility_node.rb', line 210

def to_html
  attributes.merge!(:type => @type ) if @type
  "<#{name}#{attributes.to_xml_attributes}>#{@nil_element ? '' : inner_html}</#{name}>"
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, TrueClass, FalseClass, Time, Date, Object)

    The result of typecasting value.



174
175
176
177
178
# File 'lib/nori/xml_utility_node.rb', line 174

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



195
196
197
198
199
200
# File 'lib/nori/xml_utility_node.rb', line 195

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