ROXML 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +6 -0
- data/.gitmodules +3 -0
- data/History.txt +299 -0
- data/MIT-LICENSE +18 -0
- data/README.rdoc +161 -0
- data/Rakefile +95 -0
- data/TODO +39 -0
- data/VERSION +1 -0
- data/config/website.yml +2 -0
- data/examples/amazon.rb +35 -0
- data/examples/current_weather.rb +27 -0
- data/examples/dashed_elements.rb +20 -0
- data/examples/library.rb +40 -0
- data/examples/posts.rb +27 -0
- data/examples/rails.rb +70 -0
- data/examples/twitter.rb +37 -0
- data/examples/xml/active_record.xml +70 -0
- data/examples/xml/amazon.xml +133 -0
- data/examples/xml/current_weather.xml +89 -0
- data/examples/xml/dashed_elements.xml +52 -0
- data/examples/xml/posts.xml +23 -0
- data/examples/xml/twitter.xml +422 -0
- data/lib/roxml.rb +547 -0
- data/lib/roxml/definition.rb +236 -0
- data/lib/roxml/hash_definition.rb +25 -0
- data/lib/roxml/xml.rb +43 -0
- data/lib/roxml/xml/parsers/libxml.rb +91 -0
- data/lib/roxml/xml/parsers/nokogiri.rb +77 -0
- data/lib/roxml/xml/references.rb +297 -0
- data/roxml.gemspec +201 -0
- data/spec/definition_spec.rb +486 -0
- data/spec/examples/active_record_spec.rb +40 -0
- data/spec/examples/amazon_spec.rb +54 -0
- data/spec/examples/current_weather_spec.rb +37 -0
- data/spec/examples/dashed_elements_spec.rb +20 -0
- data/spec/examples/library_spec.rb +46 -0
- data/spec/examples/post_spec.rb +24 -0
- data/spec/examples/twitter_spec.rb +32 -0
- data/spec/roxml_spec.rb +372 -0
- data/spec/shared_specs.rb +15 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +14 -0
- data/spec/support/libxml.rb +3 -0
- data/spec/support/nokogiri.rb +3 -0
- data/spec/xml/attributes_spec.rb +36 -0
- data/spec/xml/namespace_spec.rb +240 -0
- data/spec/xml/namespaces_spec.rb +32 -0
- data/spec/xml/parser_spec.rb +26 -0
- data/tasks/rdoc.rake +13 -0
- data/tasks/rspec.rake +25 -0
- data/tasks/test.rake +35 -0
- data/test/fixtures/book_malformed.xml +5 -0
- data/test/fixtures/book_pair.xml +8 -0
- data/test/fixtures/book_text_with_attribute.xml +5 -0
- data/test/fixtures/book_valid.xml +5 -0
- data/test/fixtures/book_with_authors.xml +7 -0
- data/test/fixtures/book_with_contributions.xml +9 -0
- data/test/fixtures/book_with_contributors.xml +7 -0
- data/test/fixtures/book_with_contributors_attrs.xml +7 -0
- data/test/fixtures/book_with_default_namespace.xml +9 -0
- data/test/fixtures/book_with_depth.xml +6 -0
- data/test/fixtures/book_with_octal_pages.xml +4 -0
- data/test/fixtures/book_with_publisher.xml +7 -0
- data/test/fixtures/book_with_wrapped_attr.xml +3 -0
- data/test/fixtures/dictionary_of_attr_name_clashes.xml +8 -0
- data/test/fixtures/dictionary_of_attrs.xml +6 -0
- data/test/fixtures/dictionary_of_guarded_names.xml +6 -0
- data/test/fixtures/dictionary_of_mixeds.xml +4 -0
- data/test/fixtures/dictionary_of_name_clashes.xml +10 -0
- data/test/fixtures/dictionary_of_names.xml +4 -0
- data/test/fixtures/dictionary_of_texts.xml +10 -0
- data/test/fixtures/library.xml +30 -0
- data/test/fixtures/library_uppercase.xml +30 -0
- data/test/fixtures/muffins.xml +3 -0
- data/test/fixtures/nameless_ageless_youth.xml +2 -0
- data/test/fixtures/node_with_attr_name_conflicts.xml +1 -0
- data/test/fixtures/node_with_name_conflicts.xml +4 -0
- data/test/fixtures/numerology.xml +4 -0
- data/test/fixtures/person.xml +1 -0
- data/test/fixtures/person_with_guarded_mothers.xml +13 -0
- data/test/fixtures/person_with_mothers.xml +10 -0
- data/test/mocks/dictionaries.rb +57 -0
- data/test/mocks/mocks.rb +279 -0
- data/test/support/fixtures.rb +11 -0
- data/test/test_helper.rb +34 -0
- data/test/unit/definition_test.rb +235 -0
- data/test/unit/deprecations_test.rb +24 -0
- data/test/unit/to_xml_test.rb +81 -0
- data/test/unit/xml_attribute_test.rb +39 -0
- data/test/unit/xml_block_test.rb +81 -0
- data/test/unit/xml_bool_test.rb +122 -0
- data/test/unit/xml_convention_test.rb +150 -0
- data/test/unit/xml_hash_test.rb +115 -0
- data/test/unit/xml_initialize_test.rb +49 -0
- data/test/unit/xml_name_test.rb +141 -0
- data/test/unit/xml_namespace_test.rb +31 -0
- data/test/unit/xml_object_test.rb +207 -0
- data/test/unit/xml_required_test.rb +94 -0
- data/test/unit/xml_text_test.rb +71 -0
- data/website/index.html +98 -0
- metadata +254 -0
data/.gitignore
ADDED
data/.gitmodules
ADDED
data/History.txt
ADDED
@@ -0,0 +1,299 @@
|
|
1
|
+
== 3.1 (On Github)
|
2
|
+
|
3
|
+
* major enhancements
|
4
|
+
|
5
|
+
* Add support for registering XML namespace prefixes via the xml_namespaces method
|
6
|
+
|
7
|
+
* bug fix
|
8
|
+
|
9
|
+
* References to arrays of attributes were only returning the first. No more.
|
10
|
+
|
11
|
+
== 3.0 (October 14, 2009)
|
12
|
+
|
13
|
+
* major enhancements
|
14
|
+
|
15
|
+
* Add Nokogiri support
|
16
|
+
* Remove previously deprecated functionality
|
17
|
+
* Remove REXML support
|
18
|
+
* Error on any unrecognized options
|
19
|
+
* Normalize hash declaration syntax:
|
20
|
+
* for :key => '@string', string is taken to be the :from argument
|
21
|
+
* for :key => {:from => '@string', :as => Type}, the arguments are just the same as a regular declaration
|
22
|
+
|
23
|
+
* minor enhancements
|
24
|
+
|
25
|
+
* Include 't' and 'f' in the list of possible boolean values, since rails uses them
|
26
|
+
* Remove :attrs hash syntax. Not particularly helpful & somewhat obfuscatory. Use :key, :value instead.
|
27
|
+
* Default attrs ending in '_at' to DateTime. This can be overriden via :as
|
28
|
+
* Default attrs ending in '_on' to Date. This can be overriden via :as
|
29
|
+
* Don't require rubygems within the library
|
30
|
+
* Don't mess with the load path
|
31
|
+
|
32
|
+
== 2.5.4 (October 4, 2009)
|
33
|
+
|
34
|
+
* bug fix
|
35
|
+
|
36
|
+
* Rely on REXML's #add_child and LibXML's <<, rather than #child_add which had been removed from REXML and deprecated from LibXML
|
37
|
+
|
38
|
+
== 2.5.3 (March 22, 2009)
|
39
|
+
|
40
|
+
* minor enhancement
|
41
|
+
|
42
|
+
* Work around apparently unintentional breaking change in libxml-ruby 1.1.3
|
43
|
+
|
44
|
+
== 2.5.2 (March 12, 2009)
|
45
|
+
|
46
|
+
* minor enhancements
|
47
|
+
|
48
|
+
* Remove dependency on an Object#try which conflicted with ActiveSupport 2.3's version
|
49
|
+
* Document the :to_xml option for attr references
|
50
|
+
* Require active_support directly, as it's less brittle and plays nicer with other libraries
|
51
|
+
|
52
|
+
== 2.5.1 (March 2, 2009)
|
53
|
+
|
54
|
+
* minor enhancements
|
55
|
+
|
56
|
+
* Add Document#save to REXML support, complete with XMLDecl output
|
57
|
+
|
58
|
+
* bug fixes
|
59
|
+
|
60
|
+
* rexml support has been fixed
|
61
|
+
* the first example in the readme was broken and has been fixed
|
62
|
+
|
63
|
+
== 2.5.0 (February 24, 2009)
|
64
|
+
|
65
|
+
* major enhancements
|
66
|
+
|
67
|
+
* support for mapping ActiveRecord classes. See examples/rails.rb.
|
68
|
+
* .from_xml will now use the setter for the declared variable, if one is available,
|
69
|
+
rather than directly setting the instance variable
|
70
|
+
* All declaration type arguments are now supported via the :as parameter, e.g. :as => [MyType]. Other uses are deprecated.
|
71
|
+
* All xml source path arguments are now supported via the :from and :in parameters, e.g. :from => :attr or :from => '@MyAttr'. Other uses are deprecated.
|
72
|
+
* All other options are presented separately, e.g. :cdata => true rather than :as => :cdata. Other uses are deprecated.
|
73
|
+
|
74
|
+
* minor enhancements
|
75
|
+
|
76
|
+
* .xml_attr declaration declares neither a reader nor a writer. With it you're left to your own devices.
|
77
|
+
* You can use literal [] for the [:text] object type declaration,
|
78
|
+
though they should be used in the :as parameter: :as => []
|
79
|
+
* You can use [] with your :as declarations. e.g. :as => [Float] is
|
80
|
+
equivalent to the old :as => [Float, :array]
|
81
|
+
* Show the actual call point of a deprecation, rather than some internal path
|
82
|
+
* Add support for BigDecimal and Fixnum as block shorthands [James Healy]
|
83
|
+
* Update libxml support to 0.9.6, and add it as a dependency, to ensure correct versioning, and
|
84
|
+
as it's an order of magnitude faster than rexml
|
85
|
+
|
86
|
+
* breaking changes
|
87
|
+
|
88
|
+
* :else option only applies to instances created via .from_xml
|
89
|
+
* On .from_xml, #initialize is now called with the *initialization_args before extracting attributes from the xml.
|
90
|
+
* #xml_initialize has been replaced with the #after_parse callback, which takes no arguments.
|
91
|
+
* .xml_accessor will overwrite the setter for this variable if it has already been defined. Use .xml_reader or .xml_attr,
|
92
|
+
or define your writer later, if this is not the behavior you want.
|
93
|
+
|
94
|
+
* deprecations
|
95
|
+
|
96
|
+
* Use :cdata => true rather than :as => :cdata
|
97
|
+
* Use literal [] around your regular object type, rather than :as => :array
|
98
|
+
* Use :from => :content rather than the :content object declaration type
|
99
|
+
* Specifying an unknown symbol or Class for :as will raise in 3.0
|
100
|
+
* Specifying :as with anything other than a type argument e.g. :bool, Float, [Date],
|
101
|
+
will not be supported in 3.0
|
102
|
+
* Use :from => :attr or :from => '@attribute_name' rather than the :attr
|
103
|
+
object declaration type
|
104
|
+
* Passing any type declaration outside the :as parameter is deprecated
|
105
|
+
* In 3.0, attributes ending in _on and _at will default to :as => Date and DateTime, respectively,
|
106
|
+
rather than :text
|
107
|
+
* Deprecated hash :attrs declaration syntax in favor of {:key => '@attr1', :value => '@attr2'}
|
108
|
+
* Deprecated hash {Type => 'name'} declaration syntax in favor of {:as => Type, :from => 'name}
|
109
|
+
* Deprecated String#to_utf and #to_latin.
|
110
|
+
|
111
|
+
* bug fixes
|
112
|
+
|
113
|
+
* xml_accessor now properly handles punctuation, such that the writer appears without '?' for boolean attributes
|
114
|
+
* text node contents are no longer truncated when '&' are present in the contents
|
115
|
+
* When using :as => Integer or Float, don't raise on missing element [James Healy]
|
116
|
+
|
117
|
+
== 2.4.3 (February 1, 2009)
|
118
|
+
|
119
|
+
* 1 bug fix
|
120
|
+
|
121
|
+
* Fix roxml to work in ruby 1.8.6, which has been broken since the removal of
|
122
|
+
extensions in version 2.4.1. Thanks Pat! [Pat Nakajima]
|
123
|
+
|
124
|
+
== 2.4.2 (January 31, 2009)
|
125
|
+
|
126
|
+
* 1 major enhancement
|
127
|
+
|
128
|
+
* xml_namespace for declaring Class-level, inheritable default namespaces.
|
129
|
+
|
130
|
+
* 4 minor enhancements
|
131
|
+
|
132
|
+
* add :as => Time, DateTime, and Date support
|
133
|
+
* support Pathname, IO and URI objects as #from_xml arguments
|
134
|
+
* :as => :bool now supports all capitalizations of 'true', 'false', 'yes', 'no', as well as '1' and '0'
|
135
|
+
* For basic types (:as => Integer, Float, Date, &c.), interpret empty strings just
|
136
|
+
as missing elements (by returning nil), rather than raising. Raise behavior can be
|
137
|
+
accessed by supplying your own block or using the :required option.
|
138
|
+
|
139
|
+
* 3 bug fixes
|
140
|
+
|
141
|
+
* Arrays of attrs or elements :as => :bool weren't previously supported. An oversight.
|
142
|
+
* Don't apply xml_convention if name is explicitly set
|
143
|
+
* Protect xpath operators : and / from modification via String#camelcase & such
|
144
|
+
|
145
|
+
== 2.4.1 (January 28, 2009)
|
146
|
+
|
147
|
+
* 3 minor enhancements
|
148
|
+
|
149
|
+
* remove dependency on 'extensions' gem, as we weren't using it much and it
|
150
|
+
was causing problems for some
|
151
|
+
* deprecate the 'xml' declaration in favor of the more explicit 'xml_reference'
|
152
|
+
declaration. Reorder params to make for cleaner 3.0 transition.
|
153
|
+
* deprecate '#tag_name' in favor of 'self.class.tag_name', as it's a class-specific value
|
154
|
+
|
155
|
+
== 2.4.0 (January 15, 2009)
|
156
|
+
|
157
|
+
* 1 major enhancement
|
158
|
+
|
159
|
+
* Add xml_convention to enable easy defaulting to common naming formats, such as camel-case and
|
160
|
+
underscored [Ben Woosley]
|
161
|
+
|
162
|
+
* 6 minor enhancements
|
163
|
+
|
164
|
+
* Add :frozen option for freezing values on parse [Ben Woosley]
|
165
|
+
* Attempt to minimize node creation by better matching wrappers [Ben Woosley]
|
166
|
+
* Preserve hash values where a single key maps to multiple values, return them as an array rather
|
167
|
+
any single one of them at random (as in group_by rather than index_by) [Ben Woosley]
|
168
|
+
* Deprecate #xml_name? as it's only used for triggering the xml_name warning [Ben Woosley]
|
169
|
+
* REXML parser ignores whitespace, which doesn't matter to us anyway [Ben Woosley]
|
170
|
+
* xml_name is inherited by default [Ben Woosley]
|
171
|
+
|
172
|
+
* 2 bug fixes
|
173
|
+
|
174
|
+
* Don't detect objects which define their own empty? as being absent for the purposes
|
175
|
+
of :default and :required [Ben Woosley]
|
176
|
+
* Sub-objects pick up their parent's attributes, even if they're added after
|
177
|
+
the child's use [Ben Woosley]
|
178
|
+
|
179
|
+
== 2.3.2 (December 11, 2008)
|
180
|
+
|
181
|
+
* Fix that both false and nil values were excluded from to_xml output, when only nil values should be [Ben Woosley]
|
182
|
+
|
183
|
+
== 2.3.1 (December 9, 2008)
|
184
|
+
|
185
|
+
* Add missing dependencies to extensions/enumerable and Symbol.to_proc,
|
186
|
+
which are as-yet inexplicably pre-included on my system... [Ben Woosley, Per Melin]
|
187
|
+
|
188
|
+
== 2.3 (December 7, 2008)
|
189
|
+
|
190
|
+
* Fix a bug in the application of blocks to array types [Ben Woosley]
|
191
|
+
|
192
|
+
* Objects now inherit xml attributes from their parents, as they should [Ben Woosley, Per Melin]
|
193
|
+
|
194
|
+
* Add #xml_initialize, which is called at the end of #from_xml, after the xml attributes
|
195
|
+
are set. Deprecate the half-baked xml_construct in it's favor. [Ben Woosley]
|
196
|
+
|
197
|
+
* Fix a bug in the handling of empty Hash types [Ben Woosley]
|
198
|
+
|
199
|
+
* Implement automatic bool-ification when the accessor name ends with ?. [Ben Woosley]
|
200
|
+
|
201
|
+
* Add missing dependency ActiveSupport [Ben Woosley]
|
202
|
+
|
203
|
+
* Remove support for installing as a rails plugin [Ben Woosley]
|
204
|
+
|
205
|
+
* Fix a bug where xml_construct was using the refs' names rather than their accessor names for comparison [Ben Woosley]
|
206
|
+
|
207
|
+
* Significantly reduce our footprint by selectively including smaller parts of ActiveSupport and Extensions.
|
208
|
+
This avoids problems such as the conflict between ActiveSupport's #to_json and the JSON gem's #to_json.
|
209
|
+
Thanks to Per Melin for reporting this problem. [Ben Woosley]
|
210
|
+
|
211
|
+
* Rationalize sub-element xml naming by enforcing the following precedence for the containing xml of an object:
|
212
|
+
:from of parent, xml_name of child, parent's accessor name. The previous fallback did not include xml_name.
|
213
|
+
This new behavior is more consistent, explicit, predictable, and DRY, but it is a breaking change, so a warning
|
214
|
+
is printed to alert others of this behavior change. ROXML::SILENCE_XML_NAME_WARNING may be used to deactivate this
|
215
|
+
warning. [Ben Woosley, James W. Thompson, Delynn Berry]
|
216
|
+
|
217
|
+
== 2.2 (November 2, 2008)
|
218
|
+
|
219
|
+
* fix gem dependencies [James Healy]
|
220
|
+
|
221
|
+
* Add block shorthands for Float and Integer, which precede the block argume if present [Ben Woosley]
|
222
|
+
|
223
|
+
* Add :required option to throw on absence [Ben Woosley]
|
224
|
+
|
225
|
+
* Deprecate the non-specific #parse in favor of #from_xml [Ben Woosley]
|
226
|
+
|
227
|
+
* Fix a bug whereby the default value was carrying over information from one object to another [James Healy, Ben Woosley]
|
228
|
+
|
229
|
+
* Fix support for :in on :attr elements [Ben Woosley]
|
230
|
+
|
231
|
+
* Deprecate Array#to_h in favor of Array#to_hash [Ben Woosley]
|
232
|
+
|
233
|
+
* Deprecate Object#to_latin and Object#to_utf in favor of the same methods on String [Ben Woosley]
|
234
|
+
|
235
|
+
== 2.1 (October 3, 2008)
|
236
|
+
|
237
|
+
* rake test now uses the default parser selection [Ben Woosley]
|
238
|
+
|
239
|
+
* Added rcov code coverage for tests [Anders Engström]
|
240
|
+
|
241
|
+
* Accommodate that libxml requires you to name the default namespace when available [Ben Woosley]
|
242
|
+
|
243
|
+
* Enable optional selection of a parser through the early definition of ROXML::XML_PARSER
|
244
|
+
[Ben Woosley]
|
245
|
+
|
246
|
+
* Enable fallback to the REXML parser if LibXML is unavailable [Ben Woosley]
|
247
|
+
|
248
|
+
== 2.0 (September 20, 2008)
|
249
|
+
|
250
|
+
* :text_content becomes simply :content, and is joined by :name [Ben Woosley]
|
251
|
+
|
252
|
+
* Allow hash mapping from node names and contents: [Ben Woosley]
|
253
|
+
|
254
|
+
xml_reader :name, {:key => :name,
|
255
|
+
:value => :content}, :in => 'container'
|
256
|
+
|
257
|
+
* Allow supplying a default via the :else option [Ben Woosley]
|
258
|
+
|
259
|
+
* Allow hash mapping of text and attr elements: [Ben Woosley]
|
260
|
+
|
261
|
+
xml_reader :name, {:key => {:text => 'key_name'},
|
262
|
+
:value => {:attr => 'attr_name'}}, :in => 'container'
|
263
|
+
|
264
|
+
* Allow 'xml_reader :name, [Type]' as an alternative to 'xml_reader :name, Type, :as => :array'
|
265
|
+
[Ben Woosley]
|
266
|
+
|
267
|
+
* Allow attaching a block for manipulating a value on fetch: [Ben Woosley]
|
268
|
+
|
269
|
+
xml_accessor :count, :attr => 'my_int' do |val|
|
270
|
+
Integer(val)
|
271
|
+
end
|
272
|
+
|
273
|
+
* Collapse xml_attr, xml_text and xml_object into a single api: xml, patterned after the standard
|
274
|
+
attr, and offer xml_reader and xml_accessor as well. Remove the :readonly arg in the process
|
275
|
+
[Ben Woosley]
|
276
|
+
|
277
|
+
* Attach string extensions (#to_latin, #to_utf) to Object rather than String, so we don't have to
|
278
|
+
call #to_s first every time [Ben Woosley]
|
279
|
+
|
280
|
+
* Allow a ROXML object to call its constructor on initialization with the xml_construct function
|
281
|
+
[Ben Woosley]
|
282
|
+
|
283
|
+
* Use symbols (e.g. :text_content) rather than TAG_CONSTANTS (e.g. TEXT_CONTENT) for readability
|
284
|
+
[Ben Woosley]
|
285
|
+
|
286
|
+
* Use named arguments (e.g. :as, :in) rather than positional for clarity,
|
287
|
+
position-independence, and invisible exclusion [Ben Woosley]
|
288
|
+
|
289
|
+
* Split out rails_plugin_package_task_gem [Ben Woosley]
|
290
|
+
|
291
|
+
* Increase testing significantly, particularly on new functionality & to_xml [Ben Woosley]
|
292
|
+
|
293
|
+
== 1.2 (October 10, 2007)
|
294
|
+
|
295
|
+
* Fix a bug such that the TEXT_CONTENT tag is no longer also READ_ONLY [Russ Olsen]
|
296
|
+
|
297
|
+
== 1.1 (September 24, 2006)
|
298
|
+
|
299
|
+
* Initial design & development [Zak Mandhro & Anders Engstrom]
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
The MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2004-2009 by Ben Woosley, Zak Mandhro and Anders Engstrom
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software
|
6
|
+
and associated documentation files (the "Software"), to deal in the Software without restriction,
|
7
|
+
including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
8
|
+
and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
|
9
|
+
subject to the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial
|
12
|
+
portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
|
15
|
+
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
|
16
|
+
EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
17
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
18
|
+
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,161 @@
|
|
1
|
+
ROXML Ruby Object to XML mapping library.
|
2
|
+
|
3
|
+
For more information visit:
|
4
|
+
|
5
|
+
http://roxml.rubyforge.org/rdoc/
|
6
|
+
http://empact.github.com/roxml/
|
7
|
+
http://rubyforge.org/projects/roxml/
|
8
|
+
|
9
|
+
Please submit bugs here:
|
10
|
+
|
11
|
+
http://github.com/Empact/roxml/issues
|
12
|
+
|
13
|
+
=Quick Start Guide
|
14
|
+
|
15
|
+
This is a short usage example. See ROXML::ClassMethods::Declarations and packaged test cases for more information.
|
16
|
+
|
17
|
+
==Basic Mapping
|
18
|
+
|
19
|
+
Consider an XML document representing a Library containing a number of Books. You
|
20
|
+
can map this structure to Ruby classes that provide addition useful behavior. With
|
21
|
+
ROXML, you can annotate the Ruby classes as follows:
|
22
|
+
|
23
|
+
class Book
|
24
|
+
include ROXML
|
25
|
+
|
26
|
+
xml_accessor :isbn, :from => "@ISBN" # attribute with name 'ISBN'
|
27
|
+
xml_accessor :title
|
28
|
+
xml_accessor :description, :cdata => true # text node with cdata protection
|
29
|
+
xml_accessor :author
|
30
|
+
end
|
31
|
+
|
32
|
+
class Library
|
33
|
+
include ROXML
|
34
|
+
|
35
|
+
xml_accessor :name, :from => "NAME", :cdata => true
|
36
|
+
xml_accessor :books, :as => [Book] # by default roxml searches for books for in <book> child nodes, then, if none are present, in ./books/book children
|
37
|
+
end
|
38
|
+
|
39
|
+
To create a library and put a number of books in it we could run the following code:
|
40
|
+
|
41
|
+
book = Book.new
|
42
|
+
book.isbn = "0201710897"
|
43
|
+
book.title = "The PickAxe"
|
44
|
+
book.description = "Best Ruby book out there!"
|
45
|
+
book.author = "David Thomas, Andrew Hunt, Dave Thomas"
|
46
|
+
|
47
|
+
lib = Library.new
|
48
|
+
lib.name = "Favorite Books"
|
49
|
+
lib.books = [book]
|
50
|
+
|
51
|
+
To save this information to an XML file:
|
52
|
+
|
53
|
+
doc = ROXML::XML::Document.new
|
54
|
+
doc.root = lib.to_xml
|
55
|
+
doc.save("library.xml")
|
56
|
+
|
57
|
+
To later populate the library object from the XML file:
|
58
|
+
|
59
|
+
lib = Library.from_xml(File.read("library.xml"))
|
60
|
+
|
61
|
+
Similarly, to do a one-to-one mapping between XML objects, such as book and publisher,
|
62
|
+
you would add a reference to another ROXML class. For example:
|
63
|
+
|
64
|
+
<book isbn="0974514055">
|
65
|
+
<title>Programming Ruby - 2nd Edition</title>
|
66
|
+
<description>Second edition of the great book.</description>
|
67
|
+
<publisher>
|
68
|
+
<name>Pragmatic Bookshelf</name>
|
69
|
+
</publisher>
|
70
|
+
</book>
|
71
|
+
|
72
|
+
can be mapped using the following code:
|
73
|
+
|
74
|
+
class Publisher
|
75
|
+
include ROXML
|
76
|
+
|
77
|
+
xml_accessor :name
|
78
|
+
|
79
|
+
# other important functionality
|
80
|
+
end
|
81
|
+
|
82
|
+
class BookWithPublisher
|
83
|
+
include ROXML
|
84
|
+
|
85
|
+
xml_name 'book'
|
86
|
+
xml_reader :publisher, :as => Publisher
|
87
|
+
|
88
|
+
# or, alternatively, if no class is needed to hang functionality on:
|
89
|
+
# xml_reader :publisher, :from => 'name', :in => 'publisher'
|
90
|
+
end
|
91
|
+
|
92
|
+
Note: In the above example, _xml_name_ annotation tells ROXML to set the element
|
93
|
+
name to "book" for mapping to XML. The default is XML element name is the class name in lowercase; "bookwithpublisher"
|
94
|
+
in this case.
|
95
|
+
|
96
|
+
=== Namespace Support
|
97
|
+
|
98
|
+
Namespaces are supported via the xml_namespace declaration and the :from and :namespace attr options. See spec/xml/namespace_spec.rb for usage.
|
99
|
+
|
100
|
+
== Manipulation
|
101
|
+
|
102
|
+
Extending the above examples, say you want to parse a book's page count and have it available as an Integer.
|
103
|
+
In such a case, you can extend any object with a block to manipulate it's value at parse time. For example:
|
104
|
+
|
105
|
+
class Dog
|
106
|
+
include ROXML
|
107
|
+
|
108
|
+
xml_reader(:age, :from => '@human_years', :as => Integer) {|years| years * 7 }
|
109
|
+
end
|
110
|
+
|
111
|
+
The result of the block above is stored, rather than the actual value parsed from the document.
|
112
|
+
|
113
|
+
== Construction
|
114
|
+
|
115
|
+
Object life-cycle is as follows: .from_xml is called with a first argument representing the xml
|
116
|
+
in file, string, or path form, and with optional initialization_args following.
|
117
|
+
|
118
|
+
Firt .new and thus #initialize, is called with those same initialization_args, or no args if none
|
119
|
+
are present. Then the object is populated with the attribute values from xml. Then the
|
120
|
+
#after_parse callback is called, with no arguments.
|
121
|
+
|
122
|
+
In #after_parse you can ensure that your object initialization is complete, including initialization which
|
123
|
+
requires more than one variable in concert.
|
124
|
+
|
125
|
+
E.g.:
|
126
|
+
|
127
|
+
class Measurement
|
128
|
+
include ROXML
|
129
|
+
|
130
|
+
xml_reader :units, :from => :attr
|
131
|
+
xml_reader :value, :from => :content
|
132
|
+
|
133
|
+
def initialize(value = 0, units = 'meters')
|
134
|
+
to_metric
|
135
|
+
end
|
136
|
+
|
137
|
+
private
|
138
|
+
def after_parse
|
139
|
+
# xml attributes of self are already valid
|
140
|
+
to_metric
|
141
|
+
end
|
142
|
+
|
143
|
+
def to_metric
|
144
|
+
# translate units & value into metric, for example
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
One important use of this approach is to make ROXML object which may or may not include an xml backing,
|
149
|
+
which may be used via _new_ construction as well as _from_xml_ construction.
|
150
|
+
|
151
|
+
== Selecting a parser
|
152
|
+
|
153
|
+
By default, ROXML will use Nokogiri if it is available, followed by LibXML. If you'd like to
|
154
|
+
explicitly require one or the other, you may do the following:
|
155
|
+
|
156
|
+
module ROXML
|
157
|
+
XML_PARSER = 'nokogiri' # or 'libxml'
|
158
|
+
end
|
159
|
+
require 'roxml'
|
160
|
+
|
161
|
+
For more information on available annotations, see ROXML::ClassMethods::Declarations
|