nokogiri-happymapper 0.6.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: f94968fd78baee9196d17340ee0fa5731c6f6fd1
4
- data.tar.gz: 7ca5b00acc1126a265473d583ee331beb00a50e0
2
+ SHA256:
3
+ metadata.gz: 75fd5c49ca6f39f746d0570dcf4b5cbcc53c983aeeb1d5198a4bb8108701fc46
4
+ data.tar.gz: 5e9106990b90654f2e93977381b3cd4a3901f79cdda533c2f2d6b452e67e95c8
5
5
  SHA512:
6
- metadata.gz: e1d779907f83b14a9b392d4dbcca7515dbda14bc8e9932b48a78cbaf7924df5e65adef12454c294947a7e86167dca1866900133985da9ed6cc14bf57fb392e37
7
- data.tar.gz: 5205073663f778a8b699d4d54aa63a1d171f12ee300cbc991bd7e3fb4ee2cc252fc2d4540b270ecadb75e0567bf8abceda913dae822f6c9f103275fe70822785
6
+ metadata.gz: 5bceafdb34f883e0980e914ff30bea0774436e9e105c1d89a25128f0e4bb7a1ddb17278bc971ee94578a83a399af4061ddc73813fc0edf46b5d5b35c8e6e48a0
7
+ data.tar.gz: 956560556fa3dbf7f111f61b4997645cc168f05ac8659c4f68fca2e30db8ab7e2a400ea18c6e13a35aeed81f4626d37e467e8fab116490945dd77269cfc1b4b0
@@ -1,4 +1,29 @@
1
- ## 0.6.0 / Unreleased
1
+ # Changelog
2
+
3
+ ## 0.7.0 / 2018-08-27
4
+
5
+ ### Breaking Changes
6
+
7
+ * Remove constant HappyMapper::DEFAULT_NS
8
+ * Drop support for Ruby 2.2 and below
9
+
10
+ ### Improvements
11
+
12
+ * Support Ruby 2.5
13
+ * Always sort namespaces. This adds support for JRuby.
14
+
15
+ ### Bug fixes
16
+
17
+ * Ensure `#to_xml` generates UTF-8 content
18
+ ([#88](https://github.com/mvz/happymapper/pull/88))
19
+ * Handle namespaces for nested value elements when parsing anonymously
20
+ ([#87](https://github.com/mvz/happymapper/pull/87))
21
+ * Handle attributes with a namespace that is different from the element
22
+ namespace ([#87](https://github.com/mvz/happymapper/pull/87))
23
+ * Ensure camel-cased elements have content in anonymous parse
24
+ ([#85](https://github.com/mvz/happymapper/pull/85))
25
+
26
+ ## 0.6.0 / 2017-09-17
2
27
 
3
28
  * Prevent parsing of empty string for Date, DateTime (wushugene)
4
29
  * Rescue nil dates (sarsena)
data/README.md CHANGED
@@ -1,11 +1,17 @@
1
- HappyMapper
2
- ===========
1
+ # HappyMapper
3
2
 
4
- Happymapper allows you to parse XML data and convert it quickly and easily into ruby data structures.
3
+ Happymapper allows you to parse XML data and convert it quickly and easily into
4
+ ruby data structures.
5
5
 
6
6
  This project is a fork of the great work done first by
7
7
  [jnunemaker](https://github.com/jnunemaker/happymapper).
8
8
 
9
+ [![Gem Version](https://badge.fury.io/rb/nokogiri-happymapper.svg)](https://badge.fury.io/rb/nokogiri-happymapper)
10
+ [![Build Status](https://travis-ci.org/mvz/happymapper.svg?branch=master)](https://travis-ci.org/mvz/happymapper)
11
+ [![Coverage Status](https://coveralls.io/repos/github/mvz/happymapper/badge.svg?branch=master)](https://coveralls.io/github/mvz/happymapper?branch=master)
12
+ [![Depfu](https://badges.depfu.com/badges/1707c8c2322e2ed267cf88bd4fb12b66/overview.svg)](https://depfu.com/github/mvz/happymapper)
13
+ [![Maintainability](https://api.codeclimate.com/v1/badges/491015f82bd2a45fd9d3/maintainability)](https://codeclimate.com/github/mvz/happymapper/maintainability)
14
+
9
15
  ## Major Differences
10
16
 
11
17
  * [Nokogiri](http://nokogiri.org/) support
@@ -13,26 +19,27 @@ This project is a fork of the great work done first by
13
19
  * Raw XML content parsing
14
20
  * `#to_xml` support utilizing the same HappyMapper tags
15
21
  * Numerous fixes for namespaces when using composition of classes
16
- * Fixes for instances of XML where a namespace is defined but no elements with that namespace are found
22
+ * Fixes for instances of XML where a namespace is defined but no elements
23
+ with that namespace are found
17
24
 
18
25
  ## Installation
19
26
 
20
- ### [Rubygems](https://rubyygems.org/gems/nokogiri-happymapper)
27
+ Install via rubygems:
21
28
 
22
29
  $ gem install nokogiri-happymapper
23
30
 
24
- ### [Bundler](http://gembundler.com/)
25
- Add the `nokogiri-happymapper` gem to your project's `Gemfile`.
31
+ Or add the `nokogiri-happymapper` gem to your project's `Gemfile`.
26
32
 
27
- gem 'nokogiri-happymapper', :require => 'happymapper'
33
+ gem 'nokogiri-happymapper', require: 'happymapper'
28
34
 
29
- Run the bundler command to install the gem:
35
+ Run Bundler to install the gem:
30
36
 
31
37
  $ bundle install
32
38
 
33
- # Examples
39
+ ## Examples
34
40
 
35
- Let's start with a simple example to get our feet wet. Here we have a simple example of XML that defines some address information:
41
+ Let's start with a simple example to get our feet wet. Here we have a simple
42
+ example of XML that defines some address information:
36
43
 
37
44
  <address>
38
45
  <street>Milchstrasse</street>
@@ -42,11 +49,13 @@ Let's start with a simple example to get our feet wet. Here we have a simple exa
42
49
  <country code="de">Germany</country>
43
50
  </address>
44
51
 
45
- Happymapper provides support for simple, zero configuration parsing as well as the ability to model the XML content in classes.
52
+ Happymapper provides support for simple, zero configuration parsing as well as
53
+ the ability to model the XML content in classes.
46
54
 
47
- ## HappyMapper.parse(XML)
55
+ ### HappyMapper.parse(XML)
48
56
 
49
- With no classes or configuration you can parse the example XML with little effort:
57
+ With no classes or configuration you can parse the example XML with little
58
+ effort:
50
59
 
51
60
  ```ruby
52
61
  address = HappyMapper.parse(ADDRESS_XML_DATA)
@@ -60,11 +69,14 @@ address.country.content # => Germany
60
69
 
61
70
  It is important to be aware that this no configuration parsing is limited in capacity:
62
71
 
63
- * All element names are converted to accessor methods with [underscorized](http://rubydoc.info/gems/activesupport/ActiveSupport/Inflector:underscore) names
72
+ * All element names are converted to accessor methods with
73
+ [underscorized](http://rubydoc.info/gems/activesupport/ActiveSupport/Inflector:underscore)
74
+ names
64
75
  * All value fields are left as String types
65
- * Determining if there is just one or multiple child elements is hard, so it assumes it is one until it finds another with the same name.
76
+ * Determining if there is just one or multiple child elements is hard, so it
77
+ assumes it is one until it finds another with the same name.
66
78
 
67
- ## Address.parse(XML)
79
+ ### Address.parse(XML)
68
80
 
69
81
  Happymapper will let you easily model this information as a class:
70
82
 
@@ -75,64 +87,86 @@ class Address
75
87
  include HappyMapper
76
88
 
77
89
  tag 'address'
78
- element :street, String, :tag => 'street'
79
- element :postcode, String, :tag => 'postcode'
80
- element :housenumber, Integer, :tag => 'housenumber'
81
- element :city, String, :tag => 'city'
82
- element :country, String, :tag => 'country'
90
+ element :street, String, tag: 'street'
91
+ element :postcode, String, tag: 'postcode'
92
+ element :housenumber, Integer, tag: 'housenumber'
93
+ element :city, String, tag: 'city'
94
+ element :country, String, tag: 'country'
83
95
  end
84
96
  ```
85
97
 
86
- To make a class HappyMapper compatible you simply `include HappyMapper` within the class definition. This takes care of all the work of defining all the speciality methods and magic you need to get running. As you can see we immediately start using these methods.
98
+ To make a class HappyMapper compatible you simply `include HappyMapper` within
99
+ the class definition. This takes care of all the work of defining all the
100
+ speciality methods and magic you need to get running. As you can see we
101
+ immediately start using these methods.
87
102
 
88
103
  * `tag` matches the name of the XML tag name 'address'.
89
104
 
90
- * `element` defines accessor methods for the specified symbol (e.g. `:street`,`:housenumber`) that will return the class type (e.g. `String`,`Integer`) of the XML tag specified (e.g. `:tag => 'street'`, `:tag => 'housenumber'`).
105
+ * `element` defines accessor methods for the specified symbol
106
+ (e.g. `:street`,`:housenumber`) that will return the class type
107
+ (e.g. `String`,`Integer`) of the XML tag specified
108
+ (e.g. `tag: 'street'`, `tag: 'housenumber'`).
91
109
 
92
- When you define an element with an accessor with the same name as the tag, this is the case for all the examples above, you can omit the `:tag`. These two element declaration are equivalent to each other:
110
+ When you define an element with an accessor with the same name as the tag, this
111
+ is the case for all the examples above, you can omit the `:tag`. These two
112
+ element declaration are equivalent to each other:
93
113
 
94
114
  ```ruby
95
- element :street, String, :tag => 'street'
115
+ element :street, String, tag: 'street'
96
116
  element :street, String
97
117
  ```
98
118
 
99
- Including the additional tag element is not going to hurt anything and in some cases will make it absolutely clear how these elements map to the XML. However, once you know this rule, it is hard not to want to save yourself the keystrokes.
119
+ Including the additional tag element is not going to hurt anything and in some
120
+ cases will make it absolutely clear how these elements map to the XML. However,
121
+ once you know this rule, it is hard not to want to save yourself the
122
+ keystrokes.
100
123
 
101
124
  Instead of `element` you may also use `has_one`:
102
125
 
103
126
  ```ruby
104
- element :street, String, :tag => 'street'
127
+ element :street, String, tag: 'street'
105
128
  element :street, String
106
129
  has_one :street, String
107
130
  ```
108
131
 
109
132
  These three statements are equivalent to each other.
110
133
 
111
- ## Parsing
134
+ ### Parsing
112
135
 
113
- With the mapping of the address XML articulated in our Address class it is time to parse the data:
136
+ With the mapping of the address XML articulated in our Address class it is time
137
+ to parse the data:
114
138
 
115
139
  ```ruby
116
- address = Address.parse(ADDRESS_XML_DATA, :single => true)
140
+ address = Address.parse(ADDRESS_XML_DATA, single: true)
117
141
  puts address.street
118
142
  ```
119
143
 
120
- Assuming that the constant `ADDRESS_XML_DATA` contains a string representation of the address XML data this is fairly straight-forward save for the `parse` method.
144
+ Assuming that the constant `ADDRESS_XML_DATA` contains a string representation
145
+ of the address XML data this is fairly straight-forward save for the `parse`
146
+ method.
121
147
 
122
- The `parse` method, like `tag` and `element` are all added when you included HappyMapper in the class. Parse is a wonderful, magical place that converts all these declarations that you have made into the data structure you are about to know and love.
148
+ The `parse` method, like `tag` and `element` are all added when you included
149
+ HappyMapper in the class. Parse is a wonderful, magical place that converts all
150
+ these declarations that you have made into the data structure you are about to
151
+ know and love.
123
152
 
124
- But what about the `:single => true`? Right, that is because by default when your object is all done parsing it will be an array. In this case an array with one element, but an array none the less. So the following are equivalent to each other:
153
+ But what about the `single: true`? Right, that is because by default when
154
+ your object is all done parsing it will be an array. In this case an array with
155
+ one element, but an array none the less. So the following are equivalent to
156
+ each other:
125
157
 
126
158
  ```ruby
127
159
  address = Address.parse(ADDRESS_XML_DATA).first
128
- address = Address.parse(ADDRESS_XML_DATA, :single => true)
160
+ address = Address.parse(ADDRESS_XML_DATA, single: true)
129
161
  ```
130
162
 
131
- The first one returns an array and we return the first instance, the second will do that work for us inside of parse.
163
+ The first one returns an array and we return the first instance, the second
164
+ will do that work for us inside of parse.
132
165
 
133
- ## Multiple Elements Mapping
166
+ ### Multiple Elements Mapping
134
167
 
135
- What if our address XML was a little different, perhaps we allowed multiple streets:
168
+ What if our address XML was a little different, perhaps we allowed multiple
169
+ streets:
136
170
 
137
171
  <address>
138
172
  <street>Milchstrasse</street>
@@ -143,20 +177,23 @@ What if our address XML was a little different, perhaps we allowed multiple stre
143
177
  <country code="de">Germany</country>
144
178
  </address>
145
179
 
146
- Similar to `element` or `has_one`, the declaration for when you have multiple elements you simply use:
180
+ Similar to `element` or `has_one`, the declaration for when you have multiple
181
+ elements you simply use:
147
182
 
148
183
  ```ruby
149
- has_many :streets, String, :tag => 'street'
184
+ has_many :streets, String, tag: 'street'
150
185
  ```
151
186
 
152
187
  Your resulting `streets` method will now return an array.
153
188
 
154
189
  ```ruby
155
- address = Address.parse(ADDRESS_XML_DATA, :single => true)
190
+ address = Address.parse(ADDRESS_XML_DATA, single: true)
156
191
  puts address.streets.join('\n')
157
192
  ```
158
193
 
159
- Imagine that you have to write `streets.join('\n')` for the rest of eternity throughout your code. It would be a nightmare and one that you could avoid by creating your own convenience method.
194
+ Imagine that you have to write `streets.join('\n')` for the rest of eternity
195
+ throughout your code. It would be a nightmare and one that you could avoid by
196
+ creating your own convenience method.
160
197
 
161
198
  ```ruby
162
199
  require 'happymapper'
@@ -172,17 +209,18 @@ class Address
172
209
  @streets.join('\n')
173
210
  end
174
211
 
175
- element :postcode, String, :tag => 'postcode'
176
- element :housenumber, String, :tag => 'housenumber'
177
- element :city, String, :tag => 'city'
178
- element :country, String, :tag => 'country'
212
+ element :postcode, String, tag: 'postcode'
213
+ element :housenumber, String, tag: 'housenumber'
214
+ element :city, String, tag: 'city'
215
+ element :country, String, tag: 'country'
179
216
  end
180
217
  ```
181
218
 
182
- Now when we call the method `streets` we get a single value, but we still have the instance variable `@streets` if we ever need to the values as an array.
219
+ Now when we call the method `streets` we get a single value, but we still have
220
+ the instance variable `@streets` if we ever need to the values as an array.
183
221
 
184
222
 
185
- ## Attribute Mapping
223
+ ### Attribute Mapping
186
224
 
187
225
  <address location='home'>
188
226
  <street>Milchstrasse</street>
@@ -196,13 +234,13 @@ Now when we call the method `streets` we get a single value, but we still have t
196
234
  Attributes are absolutely the same as `element` or `has_many`
197
235
 
198
236
  ```ruby
199
- attribute :location, String, :tag => 'location
237
+ attribute :location, String, tag: 'location
200
238
  ```
201
239
 
202
- Again, you can omit the tag if the attribute accessor symbol matches the name of the attribute.
203
-
240
+ Again, you can omit the tag if the attribute accessor symbol matches the name
241
+ of the attribute.
204
242
 
205
- ### Attributes On Empty Child Elements
243
+ #### Attributes On Empty Child Elements
206
244
 
207
245
  <feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom">
208
246
  <id>tag:all-the-episodes.heroku.com,2005:/tv_shows</id>
@@ -212,12 +250,14 @@ Again, you can omit the tag if the attribute accessor symbol matches the name of
212
250
  <updated>2011-07-10T06:52:27Z</updated>
213
251
  </feed>
214
252
 
215
- In this case you would need to map an element to a new `Link` class just to access `<link>`s attributes, except that there is an alternate syntax. Instead of
253
+ In this case you would need to map an element to a new `Link` class just to
254
+ access `<link>`s attributes, except that there is an alternate syntax. Instead
255
+ of
216
256
 
217
257
  ```ruby
218
258
  class Feed
219
259
  # ....
220
- has_many :links, Link, :tag => 'link', :xpath => '.'
260
+ has_many :links, Link, tag: 'link', xpath: '.'
221
261
  end
222
262
 
223
263
  class Link
@@ -232,17 +272,25 @@ end
232
272
  You can drop the `Link` class and simply replace the `has_many` on `Feed` with
233
273
 
234
274
  ```ruby
235
- element :link, String, :single => false, :attributes => { :rel => String, :type => String, :href => String }
275
+ element :link, String, single: false, attributes: { rel: String, type: String, href: String }
236
276
  ```
237
277
 
238
- As there is no content, the type given for `:link` (`String` above) is irrelevant, but `nil` won't work and other types may try to perform typecasting and fail. You can omit the :single => false for elements that only occur once within their parent.
278
+ As there is no content, the type given for `:link` (`String` above) is
279
+ irrelevant, but `nil` won't work and other types may try to perform typecasting
280
+ and fail. You can omit the single: false for elements that only occur once
281
+ within their parent.
239
282
 
240
- This syntax is most appropriate for elements that (a) have attributes but no content and (b) only occur at only one level of the heirarchy. If `<feed>` contained another element that also contained a `<link>` (as atom feeds generally do) it would be DRY-er to use the first syntax, i.e. with a separate `Link` class.
283
+ This syntax is most appropriate for elements that (a) have attributes but no
284
+ content and (b) only occur at only one level of the heirarchy. If `<feed>`
285
+ contained another element that also contained a `<link>` (as atom feeds
286
+ generally do) it would be DRY-er to use the first syntax, i.e. with a separate
287
+ `Link` class.
241
288
 
242
289
 
243
- ## Class composition (and Text Node)
290
+ ### Class composition (and Text Node)
244
291
 
245
- Our address has a country and that country element has a code. Up until this point we neglected it as we declared a `country` as being a `String`.
292
+ Our address has a country and that country element has a code. Up until this
293
+ point we neglected it as we declared a `country` as being a `String`.
246
294
 
247
295
  <address location='home'>
248
296
  <street>Milchstrasse</street>
@@ -278,33 +326,40 @@ class Address
278
326
 
279
327
  tag 'address'
280
328
 
281
- has_many :streets, String, :tag => 'street'
329
+ has_many :streets, String, tag: 'street'
282
330
 
283
331
  def streets
284
332
  @streets.join('\n')
285
333
  end
286
334
 
287
- element :postcode, String, :tag => 'postcode'
288
- element :housenumber, String, :tag => 'housenumber'
289
- element :city, String, :tag => 'city'
290
- element :country, Country, :tag => 'country'
335
+ element :postcode, String, tag: 'postcode'
336
+ element :housenumber, String, tag: 'housenumber'
337
+ element :city, String, tag: 'city'
338
+ element :country, Country, tag: 'country'
291
339
  end
292
340
  ```
293
341
 
294
- Instead of `String`, `Boolean`, or `Integer` we say that it is a `Country` and HappyMapper takes care of the details of continuing the XML mapping through the country element.
342
+ Instead of `String`, `Boolean`, or `Integer` we say that it is a `Country` and
343
+ HappyMapper takes care of the details of continuing the XML mapping through the
344
+ country element.
295
345
 
296
346
  ```ruby
297
- address = Address.parse(ADDRESS_XML_DATA, :single => true)
347
+ address = Address.parse(ADDRESS_XML_DATA, single: true)
298
348
  puts address.country.code
299
349
  ```
300
350
 
301
- A quick note, in the above example we used the constant `Country`. We could have used `'Country'`. The nice part of using the latter declaration, enclosed in quotes, is that you do not have to define your class before this class. So Country and Address can live in separate files and as long as both constants are available when it comes time to parse you are golden.
351
+ A quick note, in the above example we used the constant `Country`. We could
352
+ have used `'Country'`. The nice part of using the latter declaration, enclosed
353
+ in quotes, is that you do not have to define your class before this class. So
354
+ Country and Address can live in separate files and as long as both constants
355
+ are available when it comes time to parse you are golden.
302
356
 
303
- ## Custom XPATH
357
+ ### Custom XPATH
304
358
 
305
- ### Has One, Has Many
359
+ #### Has One, Has Many
306
360
 
307
- Getting to elements deep down within your XML can be a little more work if you did not have xpath support. Consider the following example:
361
+ Getting to elements deep down within your XML can be a little more work if you
362
+ did not have xpath support. Consider the following example:
308
363
 
309
364
  <media>
310
365
  <gallery>
@@ -320,22 +375,26 @@ Getting to elements deep down within your XML can be a little more work if you d
320
375
  </picture>
321
376
  </media>
322
377
 
323
- You may want to map the sub-elements contained buried in the 'gallery' as top level items in the media. Traditionally you could use class composition to accomplish this task, however, using the xpath attribute you have the ability to shortcut some of that work.
378
+ You may want to map the sub-elements contained buried in the 'gallery' as top
379
+ level items in the media. Traditionally you could use class composition to
380
+ accomplish this task, however, using the xpath attribute you have the ability
381
+ to shortcut some of that work.
324
382
 
325
383
  ```ruby
326
384
  class Media
327
385
  include HappyMapper
328
386
 
329
- has_one :title, String, :xpath => 'gallery/title'
330
- has_one :link, String, :xpath => 'gallery/title/@href'
387
+ has_one :title, String, xpath: 'gallery/title'
388
+ has_one :link, String, xpath: 'gallery/title/@href'
331
389
  end
332
390
  ```
333
391
 
334
- ## Shared Functionality
392
+ ### Shared Functionality
335
393
 
336
- ### Inheritance Approach
394
+ #### Inheritance Approach
337
395
 
338
- While mapping XML to objects you may arrive at a point where you have two or more very similar structures.
396
+ While mapping XML to objects you may arrive at a point where you have two or
397
+ more very similar structures.
339
398
 
340
399
  ```ruby
341
400
  class Article
@@ -361,7 +420,9 @@ class Gallery
361
420
  end
362
421
  ```
363
422
 
364
- In this example there are definitely two similarities between our two pieces of content. So much so that you might be included to create an inheritance structure to save yourself some keystrokes.
423
+ In this example there are definitely two similarities between our two pieces of
424
+ content. So much so that you might be included to create an inheritance
425
+ structure to save yourself some keystrokes.
365
426
 
366
427
  ```ruby
367
428
  class Content
@@ -385,7 +446,7 @@ class Gallery < Content
385
446
  end
386
447
  ```
387
448
 
388
- ### Module Mixins Approach
449
+ #### Module Mixins Approach
389
450
 
390
451
  You can also solve the above problem through mixins.
391
452
 
@@ -417,12 +478,17 @@ class Gallery
417
478
  end
418
479
  ```
419
480
 
420
- Here, when we include `Content` in both of these classes the module method `#included` is called and our class is given as a parameter. So we take that opportunity to do some surgery and define our happymapper elements as well as any other methods that may rely on those instance variables that come along in the package.
481
+ Here, when we include `Content` in both of these classes the module method
482
+ `#included` is called and our class is given as a parameter. So we take that
483
+ opportunity to do some surgery and define our happymapper elements as well as
484
+ any other methods that may rely on those instance variables that come along in
485
+ the package.
421
486
 
422
487
 
423
- ## Filtering with XPATH (non-greedy)
488
+ ### Filtering with XPATH (non-greedy)
424
489
 
425
- I ran into a case where I wanted to capture all the pictures that were directly under media, but not the ones contained within a gallery.
490
+ I ran into a case where I wanted to capture all the pictures that were directly
491
+ under media, but not the ones contained within a gallery.
426
492
 
427
493
  <media>
428
494
  <gallery>
@@ -445,15 +511,15 @@ require 'happymapper'
445
511
  class Media
446
512
  include HappyMapper
447
513
 
448
- has_many :galleries, Gallery, :tag => 'gallery'
449
- has_many :pictures, Picture, :tag => 'picture'
514
+ has_many :galleries, Gallery, tag: 'gallery'
515
+ has_many :pictures, Picture, tag: 'picture'
450
516
  end
451
517
  ```
452
518
 
453
519
  However when I parsed the media xml the number of pictures returned to me was 2, not 1.
454
520
 
455
521
  ```ruby
456
- pictures = Media.parse(MEDIA_XML,:single => true).pictures
522
+ pictures = Media.parse(MEDIA_XML,single: true).pictures
457
523
  pictures.length.should == 1 # => Failed Expectation
458
524
  ```
459
525
 
@@ -466,16 +532,17 @@ To limit an element from being greedy and only finding elements at the
466
532
  level of the current node you can specify an XPATH.
467
533
 
468
534
  ```ruby
469
- has_many :pictures, Picture, :tag => 'picture', :xpath => '.'
535
+ has_many :pictures, Picture, tag: 'picture', xpath: '.'
470
536
  ```
471
537
 
472
538
  `.` states that we are only interested in pictures that can be found directly
473
539
  under the current node. So when we parse again we will have only our one element.
474
540
 
475
541
 
476
- ## Namespaces
542
+ ### Namespaces
477
543
 
478
- Obviously your XML and these trivial examples are easy to map and parse because they lack the treacherous namespaces that befall most XML files.
544
+ Obviously your XML and these trivial examples are easy to map and parse because
545
+ they lack the treacherous namespaces that befall most XML files.
479
546
 
480
547
  Perhaps our `address` XML is really swarming with namespaces:
481
548
 
@@ -488,7 +555,10 @@ Perhaps our `address` XML is really swarming with namespaces:
488
555
  <prefix:country code="de">Germany</prefix:country>
489
556
  </prefix:address>
490
557
 
491
- Here again is our address example with a made up namespace called `prefix` that comes direct to use from unicornland, a very magical place indeed. Well we are going to have to do some work on our class definition and that simply adding this one liner to the `Address` class:
558
+ Here again is our address example with a made up namespace called `prefix` that
559
+ comes direct to use from unicornland, a very magical place indeed. Well we are
560
+ going to have to do some work on our class definition and that simply adding
561
+ this one liner to the `Address` class:
492
562
 
493
563
  ```ruby
494
564
  class Address
@@ -500,17 +570,21 @@ class Address
500
570
  end
501
571
  ```
502
572
 
503
- Of course, if that is too easy for you, you can append a `:namespace => 'prefix` to every one of the elements that you defined.
573
+ Of course, if that is too easy for you, you can append a `namespace: 'prefix`
574
+ to every one of the elements that you defined.
504
575
 
505
576
  ```ruby
506
- has_many :street, String, :tag => 'street', :namespace => 'prefix'
507
- element :postcode, String, :tag => 'postcode', :namespace => 'prefix'
508
- element :housenumber, String, :tag => 'housenumber', :namespace => 'prefix'
509
- element :city, String, :tag => 'city', :namespace => 'prefix'
510
- element :country, Country, :tag => 'country', :namespace => 'prefix'
577
+ has_many :street, String, tag: 'street', namespace: 'prefix'
578
+ element :postcode, String, tag: 'postcode', namespace: 'prefix'
579
+ element :housenumber, String, tag: 'housenumber', namespace: 'prefix'
580
+ element :city, String, tag: 'city', namespace: 'prefix'
581
+ element :country, Country, tag: 'country', namespace: 'prefix'
511
582
  ```
512
583
 
513
- I definitely recommend the former, as it saves you a whole hell of lot of typing. However, there are times when appending a namespace to an element declaration is important and that is when it has a different namespace then `namespsace 'prefix'`.
584
+ I definitely recommend the former, as it saves you a whole hell of lot of
585
+ typing. However, there are times when appending a namespace to an element
586
+ declaration is important and that is when it has a different namespace than
587
+ `namespace 'prefix'`.
514
588
 
515
589
  Imagine that our `country` actually belonged to a completely different namespace.
516
590
 
@@ -527,63 +601,76 @@ Imagine that our `country` actually belonged to a completely different namespace
527
601
  Well we would need to specify that namespace:
528
602
 
529
603
  ```ruby
530
- element :country, Country, :tag => 'country', :namespace => 'different'
604
+ element :country, Country, tag: 'country', namespace: 'different'
531
605
  ```
532
606
 
533
607
  With that we should be able to parse as we once did.
534
608
 
535
- ## Large Datasets (in_groups_of)
609
+ ### Large Datasets (in_groups_of)
536
610
 
537
- When dealing with large sets of XML that simply cannot or should not be placed into memory the objects can be handled in groups through the `:in_groups_of` parameter.
611
+ When dealing with large sets of XML that simply cannot or should not be placed
612
+ into memory the objects can be handled in groups through the `:in_groups_of`
613
+ parameter.
538
614
 
539
615
  ```ruby
540
- Address.parse(LARGE_ADDRESS_XML_DATA,:in_groups_of => 5) do |group|
616
+ Address.parse(LARGE_ADDRESS_XML_DATA,in_groups_of: 5) do |group|
541
617
  puts address.streets
542
618
  end
543
619
  ```
544
620
 
545
- This trivial block will parse the large set of XML data and in groups of 5 addresses at a time display the streets.
621
+ This trivial block will parse the large set of XML data and in groups of 5
622
+ addresses at a time display the streets.
546
623
 
547
- ## Saving to XML
624
+ ### Saving to XML
548
625
 
549
- Saving a class to XML is as easy as calling `#to_xml`. The end result will be the current state of your object represented as xml. Let's cover some details that are sometimes necessary and features present to make your life easier.
626
+ Saving a class to XML is as easy as calling `#to_xml`. The end result will be
627
+ the current state of your object represented as xml. Let's cover some details
628
+ that are sometimes necessary and features present to make your life easier.
550
629
 
551
630
 
552
- ### :on_save
631
+ #### :on_save
553
632
 
554
- When you are saving data to xml it is often important to change or manipulate data to a particular format. For example, a time object:
633
+ When you are saving data to xml it is often important to change or manipulate
634
+ data to a particular format. For example, a time object:
555
635
 
556
636
  ```ruby
557
- has_one :published_time, Time, :on_save => lambda {|time| time.strftime("%H:%M:%S") if time }
637
+ has_one :published_time, Time, on_save: lambda {|time| time.strftime("%H:%M:%S") if time }
558
638
  ```
559
639
 
560
- Here we add the options `:on_save` and specify a lambda which will be executed on the method call to `:published_time`.
640
+ Here we add the options `:on_save` and specify a lambda which will be executed
641
+ on the method call to `:published_time`.
561
642
 
562
- ### :state_when_nil
643
+ #### :state_when_nil
563
644
 
564
- When an element contains a nil value, or perhaps the result of the :on_save lambda correctly results in a nil value you will be happy that the element will not appear in the resulting XML. However, there are time when you will want to see that element and that's when `:state_when_nil` is there for you.
645
+ When an element contains a nil value, or perhaps the result of the :on_save
646
+ lambda correctly results in a nil value you will be happy that the element will
647
+ not appear in the resulting XML. However, there are time when you will want to
648
+ see that element and that's when `:state_when_nil` is there for you.
565
649
 
566
650
  ```ruby
567
- has_one :favorite_color, String, :state_when_nil => true
651
+ has_one :favorite_color, String, state_when_nil: true
568
652
  ```
569
653
 
570
- The resulting XML will include the 'favorite_color' element even if the favorite color has not been specified.
654
+ The resulting XML will include the 'favorite_color' element even if the
655
+ favorite color has not been specified.
571
656
 
572
- ### :read_only
657
+ #### :read_only
573
658
 
574
659
  When an element, attribute, or text node is a value that you have no interest in
575
660
  saving to XML, you can ensure that takes place by stating that it is `read only`.
576
661
 
577
662
  ```ruby
578
- has_one :modified, Boolean, :read_only => true
579
- attribute :temporary, Boolean, :read_only => true
663
+ has_one :modified, Boolean, read_only: true
664
+ attribute :temporary, Boolean, read_only: true
580
665
  ```
581
666
 
582
667
  This is useful if perhaps the incoming XML is different than the out-going XML.
583
668
 
584
- ### namespaces
669
+ #### namespaces
585
670
 
586
- Parsing the XML to objects only required you to simply specify the prefix of the namespace you wanted to parse, when you persist to xml you will need to define your namespaces so that they are correctly captured.
671
+ Parsing the XML to objects only required you to simply specify the prefix of
672
+ the namespace you wanted to parse, when you persist to xml you will need to
673
+ define your namespaces so that they are correctly captured.
587
674
 
588
675
  ```ruby
589
676
  class Address
@@ -599,7 +686,7 @@ class Address
599
686
  element :postcode, String
600
687
  element :housenumber, String
601
688
  element :city, String
602
- element :country, Country, :tag => 'country', :namespace => 'different'
689
+ element :country, Country, tag: 'country', namespace: 'different'
603
690
 
604
691
  end
605
- ```
692
+ ```