happymapper 0.2.5 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/HOW_TO_RELEASE ADDED
@@ -0,0 +1,5 @@
1
+ * Change lib/happymapper/version to new version.
2
+ * rake prepare
3
+ * git commit version bump
4
+ * git push for github
5
+ * rake release for rubyforge
data/Manifest CHANGED
@@ -1,10 +1,12 @@
1
1
  examples/amazon.rb
2
2
  examples/current_weather.rb
3
3
  examples/dashed_elements.rb
4
+ examples/multi_street_address.rb
4
5
  examples/post.rb
5
6
  examples/twitter.rb
6
7
  happymapper.gemspec
7
8
  History
9
+ HOW_TO_RELEASE
8
10
  lib/happymapper/attribute.rb
9
11
  lib/happymapper/element.rb
10
12
  lib/happymapper/item.rb
@@ -19,7 +21,9 @@ spec/fixtures/analytics.xml
19
21
  spec/fixtures/commit.xml
20
22
  spec/fixtures/current_weather.xml
21
23
  spec/fixtures/family_tree.xml
24
+ spec/fixtures/multi_street_address.xml
22
25
  spec/fixtures/multiple_namespaces.xml
26
+ spec/fixtures/nested_namespaces.xml
23
27
  spec/fixtures/pita.xml
24
28
  spec/fixtures/posts.xml
25
29
  spec/fixtures/product_default_namespace.xml
@@ -0,0 +1,15 @@
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/address_multi_street.xml')
5
+
6
+ class MultiStreetAddress
7
+ include HappyMapper
8
+
9
+ # allow primitive type to be collection
10
+ has_many :street_address, String, :tag => "streetaddress"
11
+ element :city, String
12
+ element :state_or_providence, String, :tag => "stateOfProvidence"
13
+ element :zip, String
14
+ element :country, String
15
+ end
data/happymapper.gemspec CHANGED
@@ -2,37 +2,33 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{happymapper}
5
- s.version = "0.2.5"
5
+ s.version = "0.3.0"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["John Nunemaker"]
9
- s.date = %q{2009-05-27}
9
+ s.date = %q{2009-10-04}
10
10
  s.description = %q{object to xml mapping library}
11
11
  s.email = %q{nunemaker@gmail.com}
12
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/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/analytics.xml", "spec/fixtures/commit.xml", "spec/fixtures/current_weather.xml", "spec/fixtures/family_tree.xml", "spec/fixtures/multiple_namespaces.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", "TODO", "website/css/common.css", "website/index.html"]
14
- s.has_rdoc = true
13
+ s.files = ["examples/amazon.rb", "examples/current_weather.rb", "examples/dashed_elements.rb", "examples/multi_street_address.rb", "examples/post.rb", "examples/twitter.rb", "happymapper.gemspec", "History", "HOW_TO_RELEASE", "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/analytics.xml", "spec/fixtures/commit.xml", "spec/fixtures/current_weather.xml", "spec/fixtures/family_tree.xml", "spec/fixtures/multi_street_address.xml", "spec/fixtures/multiple_namespaces.xml", "spec/fixtures/nested_namespaces.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", "TODO", "website/css/common.css", "website/index.html"]
15
14
  s.homepage = %q{http://happymapper.rubyforge.org}
16
15
  s.post_install_message = %q{May you have many happy mappings!}
17
16
  s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Happymapper", "--main", "README"]
18
17
  s.require_paths = ["lib"]
19
18
  s.rubyforge_project = %q{happymapper}
20
- s.rubygems_version = %q{1.3.1}
19
+ s.rubygems_version = %q{1.3.5}
21
20
  s.summary = %q{object to xml mapping library}
22
21
 
23
22
  if s.respond_to? :specification_version then
24
23
  current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
25
- s.specification_version = 2
24
+ s.specification_version = 3
26
25
 
27
26
  if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
28
27
  s.add_runtime_dependency(%q<libxml-ruby>, ["= 1.1.3"])
29
- s.add_development_dependency(%q<echoe>, [">= 0"])
30
28
  else
31
29
  s.add_dependency(%q<libxml-ruby>, ["= 1.1.3"])
32
- s.add_dependency(%q<echoe>, [">= 0"])
33
30
  end
34
31
  else
35
32
  s.add_dependency(%q<libxml-ruby>, ["= 1.1.3"])
36
- s.add_dependency(%q<echoe>, [">= 0"])
37
33
  end
38
34
  end
data/lib/happymapper.rb CHANGED
@@ -66,9 +66,6 @@ module HappyMapper
66
66
  end
67
67
 
68
68
  def parse(xml, options = {})
69
- # locally scoped copy of namespace for this parse run
70
- namespace = @namespace
71
-
72
69
  if xml.is_a?(XML::Node)
73
70
  node = xml
74
71
  else
@@ -81,22 +78,14 @@ module HappyMapper
81
78
  root = node.name == tag_name
82
79
  end
83
80
 
84
- # This is the entry point into the parsing pipeline, so the default
85
- # namespace prefix registered here will propagate down
86
- namespaces = node.namespaces
87
- if namespaces && namespaces.default
88
- already_assigned = namespaces.definitions.detect do |defn|
89
- namespaces.default && namespaces.default.href == defn.href && defn.prefix
90
- end
91
- namespaces.default_prefix = DEFAULT_NS unless already_assigned
92
- namespace ||= DEFAULT_NS
93
- end
81
+ namespace = @namespace || (node.namespaces && node.namespaces.default)
82
+ namespace = "#{DEFAULT_NS}:#{namespace}" if namespace
94
83
 
95
84
  xpath = root ? '/' : './/'
96
- xpath += "#{namespace}:" if namespace
85
+ xpath += "#{DEFAULT_NS}:" if namespace
97
86
  xpath += tag_name
98
87
 
99
- nodes = node.find(xpath)
88
+ nodes = node.find(xpath, Array(namespace))
100
89
  collection = nodes.collect do |n|
101
90
  obj = new
102
91
 
@@ -59,7 +59,7 @@ module HappyMapper
59
59
  def xpath(namespace = self.namespace)
60
60
  xpath = ''
61
61
  xpath += './/' if options[:deep]
62
- xpath += "#{namespace}:" if namespace
62
+ xpath += "#{DEFAULT_NS}:" if namespace
63
63
  xpath += tag
64
64
  # puts "xpath: #{xpath}"
65
65
  xpath
@@ -128,20 +128,33 @@ module HappyMapper
128
128
  end
129
129
 
130
130
  def find(node, namespace, &block)
131
- # this node has a custom namespace (that is present in the doc)
132
- if self.namespace && node.namespaces.find_by_prefix(self.namespace)
133
- # from the class definition
134
- namespace = self.namespace
135
- elsif options[:namespace] && node.namespaces.find_by_prefix(options[:namespace])
131
+ if options[:namespace] == false
132
+ namespace = nil
133
+ elsif options[:namespace]
136
134
  # from an element definition
137
- namespace = options[:namespace]
135
+ namespace = "#{DEFAULT_NS}:#{options[:namespace]}"
136
+ elsif self.namespace
137
+ # this node has a custom namespace (that is present in the doc)
138
+ namespace = "#{DEFAULT_NS}:#{self.namespace}"
138
139
  end
139
-
140
+
140
141
  if element?
141
- result = node.find_first(xpath(namespace))
142
+ if(options[:single].nil? || options[:single])
143
+ result = node.find_first(xpath(namespace), namespace)
144
+ else
145
+ result = node.find(xpath(namespace))
146
+ end
142
147
  # puts "vfxn: #{xpath} #{result.inspect}"
143
148
  if result
144
- value = yield(result)
149
+ if(options[:single].nil? || options[:single])
150
+ value = yield(result)
151
+ else
152
+ value = []
153
+
154
+ result.each do |res|
155
+ value << yield(res)
156
+ end
157
+ end
145
158
  if options[:attributes].is_a?(Hash)
146
159
  result.attributes.each do |xml_attribute|
147
160
  if attribute_options = options[:attributes][xml_attribute.name.to_sym]
@@ -1,3 +1,3 @@
1
1
  module HappyMapper
2
- Version = '0.2.5'
2
+ Version = '0.3.0'
3
3
  end
@@ -0,0 +1,9 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <address>
3
+ <streetaddress>123 Smith Dr</streetaddress>
4
+ <streetaddress>Apt 31</streetaddress>
5
+ <city>Anytown</city>
6
+ <stateOrProvince>ST<stateOrProvince>
7
+ <zip>12345</zip>
8
+ <country>USA</country>
9
+ </address>
@@ -0,0 +1,17 @@
1
+ <?xml version="1.0" encoding="UTF-8" ?>
2
+ <EDXLDistribution>
3
+ <contentObject>
4
+ <confidentiality>Sensitive</confidentiality>
5
+ <xmlContent>
6
+ <embeddedXMLContent>
7
+ <ns1:alert xmlns:ns1="http://schemas.google.com/analytics/2009">
8
+ <severity>Severe</severity>
9
+ <ns1:identifier>CDC-2006-183</ns1:identifier>
10
+ <ns1:info>
11
+ <ns1:category>Health</ns1:category>
12
+ </ns1:info>
13
+ </ns1:alert>
14
+ </embeddedXMLContent>
15
+ </xmlContent>
16
+ </contentObject>
17
+ </EDXLDistribution>
@@ -65,8 +65,8 @@ describe HappyMapper::Item do
65
65
 
66
66
  it "should prepend namespace if namespace exists" do
67
67
  item = HappyMapper::Item.new(:foo, String, :tag => 'foobar')
68
- item.namespace = 'v2'
69
- item.xpath.should == 'v2:foobar'
68
+ item.namespace = 'http://example.com'
69
+ item.xpath.should == 'happymapper:foobar'
70
70
  end
71
71
  end
72
72
 
@@ -7,7 +7,7 @@ module Analytics
7
7
  include HappyMapper
8
8
 
9
9
  tag 'property'
10
- namespace 'dxp'
10
+ namespace 'http://schemas.google.com/analytics/2009'
11
11
  attribute :name, String
12
12
  attribute :value, String
13
13
  end
@@ -19,7 +19,7 @@ module Analytics
19
19
  element :id, String
20
20
  element :updated, DateTime
21
21
  element :title, String
22
- element :table_id, String, :namespace => 'dxp', :tag => 'tableId'
22
+ element :table_id, String, :namespace => 'http://schemas.google.com/analytics/2009', :tag => 'tableId'
23
23
  has_many :properties, Property
24
24
  end
25
25
 
@@ -84,7 +84,7 @@ module FedEx
84
84
  include HappyMapper
85
85
 
86
86
  tag 'Address'
87
- namespace 'v2'
87
+ namespace 'http://fedex.com/ws/track/v2'
88
88
  element :city, String, :tag => 'City'
89
89
  element :state, String, :tag => 'StateOrProvinceCode'
90
90
  element :zip, String, :tag => 'PostalCode'
@@ -96,7 +96,7 @@ module FedEx
96
96
  include HappyMapper
97
97
 
98
98
  tag 'Events'
99
- namespace 'v2'
99
+ namespace 'http://fedex.com/ws/track/v2'
100
100
  element :timestamp, String, :tag => 'Timestamp'
101
101
  element :eventtype, String, :tag => 'EventType'
102
102
  element :eventdescription, String, :tag => 'EventDescription'
@@ -107,7 +107,7 @@ module FedEx
107
107
  include HappyMapper
108
108
 
109
109
  tag 'PackageWeight'
110
- namespace 'v2'
110
+ namespace 'http://fedex.com/ws/track/v2'
111
111
  element :units, String, :tag => 'Units'
112
112
  element :value, Integer, :tag => 'Value'
113
113
  end
@@ -116,7 +116,7 @@ module FedEx
116
116
  include HappyMapper
117
117
 
118
118
  tag 'TrackDetails'
119
- namespace 'v2'
119
+ namespace 'http://fedex.com/ws/track/v2'
120
120
  element :tracking_number, String, :tag => 'TrackingNumber'
121
121
  element :status_code, String, :tag => 'StatusCode'
122
122
  element :status_desc, String, :tag => 'StatusDescription'
@@ -131,7 +131,7 @@ module FedEx
131
131
  include HappyMapper
132
132
 
133
133
  tag 'Notifications'
134
- namespace 'v2'
134
+ namespace 'http://fedex.com/ws/track/v2'
135
135
  element :severity, String, :tag => 'Severity'
136
136
  element :source, String, :tag => 'Source'
137
137
  element :code, Integer, :tag => 'Code'
@@ -143,7 +143,7 @@ module FedEx
143
143
  include HappyMapper
144
144
 
145
145
  tag 'TransactionDetail'
146
- namespace 'v2'
146
+ namespace 'http://fedex.com/ws/track/v2'
147
147
  element :cust_tran_id, String, :tag => 'CustomerTransactionId'
148
148
  end
149
149
 
@@ -151,7 +151,7 @@ module FedEx
151
151
  include HappyMapper
152
152
 
153
153
  tag 'TrackReply'
154
- namespace 'v2'
154
+ namespace 'http://fedex.com/ws/track/v2'
155
155
  element :highest_severity, String, :tag => 'HighestSeverity'
156
156
  element :more_data, Boolean, :tag => 'MoreData'
157
157
  has_many :notifications, Notification, :tag => 'Notifications'
@@ -215,7 +215,7 @@ class CurrentWeather
215
215
  include HappyMapper
216
216
 
217
217
  tag 'ob'
218
- namespace 'aws'
218
+ namespace 'http://www.aws.com/aws'
219
219
  element :temperature, Integer, :tag => 'temp'
220
220
  element :feels_like, Integer, :tag => 'feels-like'
221
221
  element :current_condition, String, :tag => 'current-condition', :attributes => {:icon => String}
@@ -243,7 +243,7 @@ module PITA
243
243
  element :asin, String, :tag => 'ASIN'
244
244
  element :detail_page_url, URI, :tag => 'DetailPageURL', :parser => :parse
245
245
  element :manufacturer, String, :tag => 'Manufacturer', :deep => true
246
- element :point, String, :tag => 'point', :namespace => 'georss'
246
+ element :point, String, :tag => 'point', :namespace => 'http://www.georss.org/georss'
247
247
  element :product_group, ProductGroup, :tag => 'ProductGroup', :deep => true, :parser => :new, :raw => true
248
248
  end
249
249
 
@@ -578,4 +578,50 @@ describe HappyMapper do
578
578
  # tree.people.first.modified.should == Time.utc(2008, 1, 3, 16, 41, 31) # 2008-01-03T09:41:31-07:00
579
579
  # tree.people.first.id.should == 'KWQS-BBQ'
580
580
  end
581
+
582
+ describe 'nested elements with namespaces' do
583
+ module Namespaces
584
+ class Info
585
+ include HappyMapper
586
+ namespace 'http://schemas.google.com/analytics/2009'
587
+ element :category, String
588
+ end
589
+
590
+ class Alert
591
+ include HappyMapper
592
+ namespace 'http://schemas.google.com/analytics/2009'
593
+
594
+ element :identifier, String
595
+ element :severity, String, :namespace => false
596
+ has_one :info, Info
597
+ end
598
+ class Distribution
599
+ include HappyMapper
600
+
601
+ tag 'EDXLDistribution'
602
+ has_one :alert, Alert
603
+ end
604
+ end
605
+
606
+ def mapping
607
+ @mapping ||= Namespaces::Distribution.parse(fixture_file('nested_namespaces.xml'))
608
+ end
609
+
610
+ it "should parse elements with inline namespace" do
611
+ lambda { mapping }.should_not raise_error
612
+ end
613
+
614
+ it "should map elements with inline namespace" do
615
+ mapping.alert.identifier.should == 'CDC-2006-183'
616
+ end
617
+
618
+ it "should map sub elements of with nested namespace" do
619
+ mapping.alert.info.category.should == 'Health'
620
+ end
621
+
622
+ it "should map elements without a namespace" do
623
+ mapping.alert.severity.should == 'Severe'
624
+ end
625
+ end
626
+
581
627
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: happymapper
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.5
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Nunemaker
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-05-27 00:00:00 -04:00
12
+ date: 2009-10-04 00:00:00 -04:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -22,16 +22,6 @@ dependencies:
22
22
  - !ruby/object:Gem::Version
23
23
  version: 1.1.3
24
24
  version:
25
- - !ruby/object:Gem::Dependency
26
- name: echoe
27
- type: :development
28
- version_requirement:
29
- version_requirements: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - ">="
32
- - !ruby/object:Gem::Version
33
- version: "0"
34
- version:
35
25
  description: object to xml mapping library
36
26
  email: nunemaker@gmail.com
37
27
  executables: []
@@ -50,10 +40,12 @@ files:
50
40
  - examples/amazon.rb
51
41
  - examples/current_weather.rb
52
42
  - examples/dashed_elements.rb
43
+ - examples/multi_street_address.rb
53
44
  - examples/post.rb
54
45
  - examples/twitter.rb
55
46
  - happymapper.gemspec
56
47
  - History
48
+ - HOW_TO_RELEASE
57
49
  - lib/happymapper/attribute.rb
58
50
  - lib/happymapper/element.rb
59
51
  - lib/happymapper/item.rb
@@ -68,7 +60,9 @@ files:
68
60
  - spec/fixtures/commit.xml
69
61
  - spec/fixtures/current_weather.xml
70
62
  - spec/fixtures/family_tree.xml
63
+ - spec/fixtures/multi_street_address.xml
71
64
  - spec/fixtures/multiple_namespaces.xml
65
+ - spec/fixtures/nested_namespaces.xml
72
66
  - spec/fixtures/pita.xml
73
67
  - spec/fixtures/posts.xml
74
68
  - spec/fixtures/product_default_namespace.xml
@@ -87,6 +81,8 @@ files:
87
81
  - website/index.html
88
82
  has_rdoc: true
89
83
  homepage: http://happymapper.rubyforge.org
84
+ licenses: []
85
+
90
86
  post_install_message: May you have many happy mappings!
91
87
  rdoc_options:
92
88
  - --line-numbers
@@ -112,9 +108,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
112
108
  requirements: []
113
109
 
114
110
  rubyforge_project: happymapper
115
- rubygems_version: 1.3.1
111
+ rubygems_version: 1.3.5
116
112
  signing_key:
117
- specification_version: 2
113
+ specification_version: 3
118
114
  summary: object to xml mapping library
119
115
  test_files: []
120
116