kdonovan-happymapper 0.3.4

Sign up to get free protection for your applications and to get access to all the features.
data/History ADDED
@@ -0,0 +1,77 @@
1
+ == 0.3.4
2
+ * 1 major enhancement, 1 minor enhancement
3
+ * Allow Marshaling HappyMapper objects
4
+ * Store raw xml when parsing objects (to_xml doesn't always retain same attributes)
5
+
6
+ == 0.3.3
7
+ * 1 bug fix 2 minor enhancements
8
+ * Don't serialize nil elements of primitive type (jimmyz)
9
+ * Added the xml version/encoding header to serialized xml string on to_xml (jimmyz)
10
+ * Bug fix: Don't parse deep on non-primitive elements unless :deep => true (jimmyz)
11
+
12
+ == 0.3.2
13
+ * 1 bug fix
14
+ * to_xml_node was blowing up if a non-primitive element was nil. Fixed (jimmyz)
15
+
16
+ == 0.3.1
17
+ * 1 minor tweak
18
+ * Added to_xml and namespace_url code to the family_tree.rb example
19
+
20
+ == 0.3.0
21
+ * 5 major enhancements, 2 minor enhancements, 1 bug fixes
22
+ * to_xml methods attach namespaces to the root element and add the namespaces to the elements (if a namespace_url is specified)
23
+ * Modified namespace method to accept a hash {'prefix' => 'http://example.com/v1'} OR 'prefix'
24
+ * Added namespace_url method to set and read a full namespace URL. This adds much better stability in case prefixes change.
25
+ * Added to_xml method to HappyMapper Module to serialize objects to string
26
+ * Added to_xml_node method to HappyMapper Module to serialize objects to LibXML::XML::Node
27
+ * Full support for creating happymapper elements from scratch. has_many instance vars default to []
28
+ * Support for has_many with a primitive type (String, Boolean, etc.)
29
+ * fix for issue #8: http://jnunemaker.lighthouseapp.com/projects/20014-happy-mapper/tickets/8
30
+
31
+ == 0.2.2
32
+ * 2 minor tweaks
33
+ * removed GC.start (libxml recommended this) as setting nodes to nil should be enough, specs run 3-4x faster (Brandon Keepers)
34
+ * renamed get_tag_name to tag_name (Brandon Keepers)
35
+ * removed libxml helpers as they are no longer needed
36
+
37
+ == 0.2.1
38
+ * 1 minor fix, 3 major enhancements
39
+ * fixed warnings about using XML::Parser (mojodna)
40
+ * Improved namespace support, now handles multiple namespaces and allows namespaces to be set item wide or on a per element basis (mojodna)
41
+ * Auto detect root nodes (mojodna)
42
+ * Type coercion (mojodna)
43
+
44
+ == 0.2.0
45
+ * 1 major enhancement, 2 minor ehancements
46
+ * Automatic handling of namespaces (part by Robert Lowrey and rest by John Nunemaker)
47
+ * Added :root option to tag method. This allows setting an object as the root element, which sets xpath to use / and sets single to true
48
+ * Now defaulting tag names for classes in modules to last constant downcased
49
+
50
+ == 0.1.7 2009-01-29
51
+ * 1 minor enhancement
52
+ * Support dashes in elements (Josh Nichols)
53
+
54
+ == 0.1.6 2009-01-17
55
+ * 1 minor enhancement:
56
+ * added support for nested collection elements (Justin Marney)
57
+
58
+ == 0.1.5 2009-01-05
59
+ * 1 major enhancement:
60
+ * Updated to latest version of libxml-ruby (lightningdb)
61
+
62
+ == 0.1.4 2009-01-05
63
+ * 1 major enhancement:
64
+ * Fixed parsing when the object is the root node. (Garret Alfert)
65
+
66
+ == 0.1.3 2008-12-31
67
+ * 1 major enhancement:
68
+ * Added parsing of attributes of elements that are also mapped, see current_weather.rb for example (jeremyf)
69
+
70
+ == 0.1.2 2008-12-12
71
+ * 1 major enhancement:
72
+ * Fixed that :deep only worked for first item (dvrensk)
73
+
74
+ == 0.1.0 2008-11-16
75
+
76
+ * 1 major enhancement:
77
+ * Initial release
data/License ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008 John Nunemaker
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Manifest ADDED
@@ -0,0 +1,40 @@
1
+ examples/amazon.rb
2
+ examples/current_weather.rb
3
+ examples/dashed_elements.rb
4
+ examples/family_tree.rb
5
+ examples/post.rb
6
+ examples/twitter.rb
7
+ happymapper.gemspec
8
+ History
9
+ lib/happymapper/attribute.rb
10
+ lib/happymapper/element.rb
11
+ lib/happymapper/item.rb
12
+ lib/happymapper/version.rb
13
+ lib/happymapper.rb
14
+ License
15
+ Manifest
16
+ Rakefile
17
+ README
18
+ spec/fixtures/address.xml
19
+ spec/fixtures/commit.xml
20
+ spec/fixtures/current_weather.xml
21
+ spec/fixtures/family_tree.xml
22
+ spec/fixtures/multiple_namespaces.xml
23
+ spec/fixtures/partial_posts.xml
24
+ spec/fixtures/pita.xml
25
+ spec/fixtures/posts.xml
26
+ spec/fixtures/product_default_namespace.xml
27
+ spec/fixtures/product_no_namespace.xml
28
+ spec/fixtures/product_single_namespace.xml
29
+ spec/fixtures/radar.xml
30
+ spec/fixtures/statuses.xml
31
+ spec/happymapper_attribute_spec.rb
32
+ spec/happymapper_element_spec.rb
33
+ spec/happymapper_item_spec.rb
34
+ spec/happymapper_spec.rb
35
+ spec/spec.opts
36
+ spec/spec_helper.rb
37
+ spec/xml_helper.rb
38
+ TODO
39
+ website/css/common.css
40
+ website/index.html
data/README ADDED
@@ -0,0 +1,10 @@
1
+ = happymapper
2
+
3
+ == DESCRIPTION:
4
+
5
+ An extension of jimmyz-happymapper (which adds to_xml to happymapper) adding in the ability to Marshal happymapper classes.
6
+
7
+ Parents:
8
+ * http://github.com/jimmyz/happymapper/tree/master
9
+ * http://github.com/jnunemaker/happymapper/tree/master
10
+
data/Rakefile ADDED
@@ -0,0 +1,43 @@
1
+ ProjectName = 'happymapper'
2
+ WebsitePath = "jnunemaker@rubyforge.org:/var/www/gforge-projects/#{ProjectName}"
3
+
4
+ require 'rubygems'
5
+ require 'rake'
6
+ require 'echoe'
7
+ require 'spec/rake/spectask'
8
+ require "lib/#{ProjectName}/version"
9
+
10
+ Echoe.new(ProjectName, HappyMapper::Version) do |p|
11
+ p.description = "object to xml mapping library"
12
+ p.install_message = "May you have many happy mappings!"
13
+ p.url = "http://#{ProjectName}.rubyforge.org"
14
+ p.author = "John Nunemaker"
15
+ p.email = "nunemaker@gmail.com"
16
+ p.extra_deps = [['libxml-ruby', '= 0.9.8']]
17
+ p.need_tar_gz = false
18
+ p.docs_host = WebsitePath
19
+ end
20
+
21
+ desc 'Upload website files to rubyforge'
22
+ task :website do
23
+ sh %{rsync -av website/ #{WebsitePath}}
24
+ Rake::Task['website_docs'].invoke
25
+ end
26
+
27
+ task :website_docs do
28
+ Rake::Task['redocs'].invoke
29
+ sh %{rsync -av doc/ #{WebsitePath}/docs}
30
+ end
31
+
32
+ desc 'Preps the gem for a new release'
33
+ task :prepare do
34
+ %w[manifest build_gemspec].each do |task|
35
+ Rake::Task[task].invoke
36
+ end
37
+ end
38
+
39
+ Rake::Task[:default].prerequisites.clear
40
+ task :default => :spec
41
+ Spec::Rake::SpecTask.new do |t|
42
+ t.spec_files = FileList["spec/**/*_spec.rb"]
43
+ end
data/TODO ADDED
File without changes
@@ -0,0 +1,34 @@
1
+ dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ require File.join(dir, 'happymapper')
3
+
4
+ file_contents = File.read(dir + '/../spec/fixtures/pita.xml')
5
+
6
+ # The document `pita.xml` contains both a default namespace and the 'georss'
7
+ # namespace (for the 'point' element).
8
+ module PITA
9
+ class Item
10
+ include HappyMapper
11
+
12
+ tag 'Item' # if you put class in module you need tag
13
+ element :asin, String, :tag => 'ASIN'
14
+ element :detail_page_url, String, :tag => 'DetailPageURL'
15
+ element :manufacturer, String, :tag => 'Manufacturer', :deep => true
16
+ # this is the only element that exists in a different namespace, so it
17
+ # must be explicitly specified
18
+ element :point, String, :tag => 'point', :namespace => 'georss'
19
+ end
20
+
21
+ class Items
22
+ include HappyMapper
23
+
24
+ tag 'Items' # if you put class in module you need tag
25
+ element :total_results, Integer, :tag => 'TotalResults'
26
+ element :total_pages, Integer, :tag => 'TotalPages'
27
+ has_many :items, Item
28
+ end
29
+ end
30
+
31
+ item = PITA::Items.parse(file_contents, :single => true)
32
+ item.items.each do |i|
33
+ puts i.asin, i.detail_page_url, i.manufacturer, ''
34
+ end
@@ -0,0 +1,21 @@
1
+ dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ require File.join(dir, 'happymapper')
3
+
4
+ file_contents = File.read(dir + '/../spec/fixtures/current_weather.xml')
5
+
6
+ class CurrentWeather
7
+ include HappyMapper
8
+
9
+ tag 'ob'
10
+ namespace 'aws'
11
+ element :temperature, Integer, :tag => 'temp'
12
+ element :feels_like, Integer, :tag => 'feels-like'
13
+ element :current_condition, String, :tag => 'current-condition', :attributes => {:icon => String}
14
+ end
15
+
16
+ CurrentWeather.parse(file_contents).each do |current_weather|
17
+ puts "temperature: #{current_weather.temperature}"
18
+ puts "feels_like: #{current_weather.feels_like}"
19
+ puts "current_condition: #{current_weather.current_condition}"
20
+ puts "current_condition.icon: #{current_weather.current_condition.icon}"
21
+ end
@@ -0,0 +1,20 @@
1
+ dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ require File.join(dir, 'happymapper')
3
+
4
+ file_contents = File.read(dir + '/../spec/fixtures/commit.xml')
5
+
6
+ module GitHub
7
+ class Commit
8
+ include HappyMapper
9
+
10
+ tag "commit"
11
+ element :url, String
12
+ element :tree, String
13
+ element :message, String
14
+ element :id, String
15
+ element :'committed-date', Date
16
+ end
17
+ end
18
+
19
+ commit = GitHub::Commit.parse(file_contents)
20
+ puts commit.committed_date, commit.url, commit.id
@@ -0,0 +1,55 @@
1
+ dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ require File.join(dir, 'happymapper')
3
+
4
+ file_contents = File.read(dir + '/../spec/fixtures/family_tree.xml')
5
+
6
+ module FamilySearch
7
+ class AlternateIds
8
+ include HappyMapper
9
+
10
+ tag 'alternateIds'
11
+ namespace 'fsapi-v1' => 'http://api.familysearch.org/v1'
12
+ has_many :ids, String, :tag => 'id'
13
+ end
14
+
15
+ class Information
16
+ include HappyMapper
17
+
18
+ namespace 'fsapi-v1' => 'http://api.familysearch.org/v1'
19
+ has_one :alternateIds, AlternateIds
20
+ end
21
+
22
+ class Person
23
+ include HappyMapper
24
+
25
+ namespace_url 'http://api.familysearch.org/familytree/v1'
26
+ attribute :version, String
27
+ attribute :modified, Time
28
+ attribute :id, String
29
+ has_one :information, Information
30
+ end
31
+
32
+ class Persons
33
+ include HappyMapper
34
+
35
+ namespace_url 'http://api.familysearch.org/familytree/v1'
36
+ has_many :person, Person
37
+ end
38
+
39
+ class FamilyTree
40
+ include HappyMapper
41
+
42
+ tag 'familytree'
43
+ namespace_url 'http://api.familysearch.org/familytree/v1'
44
+ attribute :version, String
45
+ attribute :status_message, String, :tag => 'statusMessage'
46
+ attribute :status_code, String, :tag => 'statusCode'
47
+ has_one :persons, Persons
48
+ end
49
+ end
50
+
51
+ familytree = FamilySearch::FamilyTree.parse(file_contents)
52
+ familytree.persons.person.each do |p|
53
+ puts p.id, p.information.alternateIds.ids, ''
54
+ end
55
+ puts familytree.to_xml
data/examples/post.rb ADDED
@@ -0,0 +1,19 @@
1
+ dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ require File.join(dir, 'happymapper')
3
+
4
+ file_contents = File.read(dir + '/../spec/fixtures/posts.xml')
5
+
6
+ class Post
7
+ include HappyMapper
8
+
9
+ attribute :href, String
10
+ attribute :hash, String
11
+ attribute :description, String
12
+ attribute :tag, String
13
+ attribute :time, DateTime
14
+ attribute :others, Integer
15
+ attribute :extended, String
16
+ end
17
+
18
+ posts = Post.parse(file_contents)
19
+ posts.each { |post| puts post.description, post.href, post.extended, '' }
@@ -0,0 +1,37 @@
1
+ dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ require File.join(dir, 'happymapper')
3
+
4
+ file_contents = File.read(dir + '/../spec/fixtures/statuses.xml')
5
+
6
+ class User
7
+ include HappyMapper
8
+
9
+ element :id, Integer
10
+ element :name, String
11
+ element :screen_name, String
12
+ element :location, String
13
+ element :description, String
14
+ element :profile_image_url, String
15
+ element :url, String
16
+ element :protected, Boolean
17
+ element :followers_count, Integer
18
+ end
19
+
20
+ class Status
21
+ include HappyMapper
22
+
23
+ element :id, Integer
24
+ element :text, String
25
+ element :created_at, Time
26
+ element :source, String
27
+ element :truncated, Boolean
28
+ element :in_reply_to_status_id, Integer
29
+ element :in_reply_to_user_id, Integer
30
+ element :favorited, Boolean
31
+ has_one :user, User
32
+ end
33
+
34
+ statuses = Status.parse(file_contents)
35
+ statuses.each do |status|
36
+ puts status.user.name, status.user.screen_name, status.text, status.source, ''
37
+ end
@@ -0,0 +1,35 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{happymapper}
5
+ s.version = "0.3.4"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["John Nunemaker"]
9
+ s.date = %q{2009-02-21}
10
+ s.description = %q{object to xml mapping library}
11
+ s.email = %q{nunemaker@gmail.com}
12
+ s.extra_rdoc_files = ["lib/happymapper/attribute.rb", "lib/happymapper/element.rb", "lib/happymapper/item.rb", "lib/happymapper/version.rb", "lib/happymapper.rb", "README", "TODO"]
13
+ s.files = ["examples/amazon.rb", "examples/current_weather.rb", "examples/dashed_elements.rb", "examples/family_tree.rb", "examples/post.rb", "examples/twitter.rb", "happymapper.gemspec", "History", "lib/happymapper/attribute.rb", "lib/happymapper/element.rb", "lib/happymapper/item.rb", "lib/happymapper/version.rb", "lib/happymapper.rb", "License", "Manifest", "Rakefile", "README", "spec/fixtures/address.xml", "spec/fixtures/commit.xml", "spec/fixtures/current_weather.xml", "spec/fixtures/family_tree.xml", "spec/fixtures/multiple_namespaces.xml", "spec/fixtures/partial_posts.xml", "spec/fixtures/pita.xml", "spec/fixtures/posts.xml", "spec/fixtures/product_default_namespace.xml", "spec/fixtures/product_no_namespace.xml", "spec/fixtures/product_single_namespace.xml", "spec/fixtures/radar.xml", "spec/fixtures/statuses.xml", "spec/happymapper_attribute_spec.rb", "spec/happymapper_element_spec.rb", "spec/happymapper_item_spec.rb", "spec/happymapper_spec.rb", "spec/spec.opts", "spec/spec_helper.rb", "spec/xml_helper.rb", "TODO", "website/css/common.css", "website/index.html"]
14
+ s.has_rdoc = true
15
+ s.homepage = %q{http://happymapper.rubyforge.org}
16
+ s.post_install_message = %q{May you have many happy mappings!}
17
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Happymapper", "--main", "README"]
18
+ s.require_paths = ["lib"]
19
+ s.rubyforge_project = %q{happymapper}
20
+ s.rubygems_version = %q{1.3.1}
21
+ s.summary = %q{object to xml mapping library}
22
+
23
+ if s.respond_to? :specification_version then
24
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
25
+ s.specification_version = 2
26
+
27
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
28
+ s.add_runtime_dependency(%q<libxml-ruby>, ["= 0.9.8"])
29
+ else
30
+ s.add_dependency(%q<libxml-ruby>, ["= 0.9.8"])
31
+ end
32
+ else
33
+ s.add_dependency(%q<libxml-ruby>, ["= 0.9.8"])
34
+ end
35
+ end
@@ -0,0 +1,3 @@
1
+ module HappyMapper
2
+ class Attribute < Item; end
3
+ end
@@ -0,0 +1,3 @@
1
+ module HappyMapper
2
+ class Element < Item; end
3
+ end
@@ -0,0 +1,175 @@
1
+ module HappyMapper
2
+ class Item
3
+ attr_accessor :name, :type, :tag, :options, :namespace
4
+
5
+ Types = [String, Float, Time, Date, DateTime, Integer, Boolean]
6
+
7
+ # options:
8
+ # :deep => Boolean False to only parse element's children, True to include
9
+ # grandchildren and all others down the chain (// in expath)
10
+ # :namespace => String Element's namespace if it's not the global or inherited
11
+ # default
12
+ # :parser => Symbol Class method to use for type coercion.
13
+ # :raw => Boolean Use raw node value (inc. tags) when parsing.
14
+ # :single => Boolean False if object should be collection, True for single object
15
+ # :tag => String Element name if it doesn't match the specified name.
16
+ def initialize(name, type, o={})
17
+ self.name = name.to_s
18
+ self.type = type
19
+ self.tag = o.delete(:tag) || name.to_s
20
+ self.namespace = o.delete(:namespace)
21
+ self.options = {:single => true }.merge o
22
+
23
+ @xml_type = self.class.to_s.split('::').last.downcase
24
+ end
25
+
26
+ def from_xml_node(node, namespace)
27
+ if primitive?
28
+ find(node, namespace) do |n|
29
+ if n.respond_to?(:content)
30
+ typecast(n.content)
31
+ else
32
+ typecast(n.to_s)
33
+ end
34
+ end
35
+ else
36
+ if options[:parser]
37
+ find(node, namespace) do |n|
38
+ if n.respond_to?(:content) && !options[:raw]
39
+ value = n.content
40
+ else
41
+ value = n.to_s
42
+ end
43
+
44
+ begin
45
+ type.send(options[:parser].to_sym, value)
46
+ rescue
47
+ nil
48
+ end
49
+ end
50
+ else
51
+ type.parse(node, options)
52
+ end
53
+ end
54
+ end
55
+
56
+ def to_xml_node(value, root_node = nil)
57
+ if primitive?
58
+ node = XML::Node.new(@tag)
59
+ node << value.to_s
60
+ # assign a namespace
61
+ if @namespace && root_node
62
+ namespace_object = root_node.namespaces.find_by_prefix @namespace
63
+ node.namespaces.namespace = namespace_object
64
+ end
65
+ node
66
+ else
67
+ value.to_xml_node(root_node) unless value.nil?
68
+ end
69
+ end
70
+
71
+ def xpath(namespace = self.namespace)
72
+ xpath = ''
73
+ xpath += './/' if options[:deep]
74
+ xpath += "#{namespace}:" if namespace
75
+ xpath += tag
76
+ # puts "xpath: #{xpath}"
77
+ xpath
78
+ end
79
+
80
+ def primitive?
81
+ Types.include?(type)
82
+ end
83
+
84
+ def element?
85
+ @xml_type == 'element'
86
+ end
87
+
88
+ def attribute?
89
+ !element?
90
+ end
91
+
92
+ def method_name
93
+ @method_name ||= name.tr('-', '_')
94
+ end
95
+
96
+ def typecast(value)
97
+ return value if value.kind_of?(type) || value.nil?
98
+ begin
99
+ if type == String then value.to_s
100
+ elsif type == Float then value.to_f
101
+ elsif type == Time then Time.parse(value.to_s)
102
+ elsif type == Date then Date.parse(value.to_s)
103
+ elsif type == DateTime then DateTime.parse(value.to_s)
104
+ elsif type == Boolean then ['true', 't', '1'].include?(value.to_s.downcase)
105
+ elsif type == Integer
106
+ # ganked from datamapper
107
+ value_to_i = value.to_i
108
+ if value_to_i == 0 && value != '0'
109
+ value_to_s = value.to_s
110
+ begin
111
+ Integer(value_to_s =~ /^(\d+)/ ? $1 : value_to_s)
112
+ rescue ArgumentError
113
+ nil
114
+ end
115
+ else
116
+ value_to_i
117
+ end
118
+ else
119
+ value
120
+ end
121
+ rescue
122
+ value
123
+ end
124
+ end
125
+
126
+ private
127
+ def find(node, namespace, &block)
128
+ # this node has a custom namespace (that is present in the doc)
129
+ if self.namespace && node.namespaces.find_by_prefix(self.namespace)
130
+ # from the class definition
131
+ namespace = self.namespace
132
+ elsif options[:namespace] && node.namespaces.find_by_prefix(options[:namespace])
133
+ # from an element definition
134
+ namespace = options[:namespace]
135
+ end
136
+
137
+ if element?
138
+ if options[:single]
139
+ result = node.find_first(xpath(namespace))
140
+ if result
141
+ value = yield(result)
142
+ handle_attributes_option(result,value)
143
+ value
144
+ else
145
+ nil
146
+ end
147
+ else
148
+ results = node.find(xpath(namespace)).collect do |result|
149
+ value = yield(result)
150
+ handle_attributes_option(result,value)
151
+ value
152
+ end
153
+ results
154
+ end
155
+ else
156
+ yield(node[tag]) unless node[tag].nil?
157
+ end
158
+ end
159
+
160
+ def handle_attributes_option(result, value)
161
+ if options[:attributes].is_a?(Hash)
162
+ result.attributes.each do |xml_attribute|
163
+ if attribute_options = options[:attributes][xml_attribute.name.to_sym]
164
+ attribute_value = Attribute.new(xml_attribute.name.to_sym, *attribute_options).from_xml_node(result, namespace)
165
+ result.instance_eval <<-EOV
166
+ def value.#{xml_attribute.name}
167
+ #{attribute_value.inspect}
168
+ end
169
+ EOV
170
+ end
171
+ end
172
+ end
173
+ end
174
+ end
175
+ end
@@ -0,0 +1,3 @@
1
+ module HappyMapper
2
+ Version = '0.3.3'
3
+ end