README.rdoc in roxml-2.4.3 vs README.rdoc in roxml-2.5.0
- old
+ new
@@ -12,21 +12,21 @@
ROXML, you can annotate the Ruby classes as follows:
class Book
include ROXML
- xml_reader :isbn, :attr => "ISBN" # attribute with name 'ISBN'
+ xml_reader :isbn, :from => "@ISBN" # attribute with name 'ISBN'
xml_reader :title
- xml_reader :description, :as => :cdata # text node with cdata protection
+ xml_reader :description, :cdata => true # text node with cdata protection
xml_reader :author
end
class Library
include ROXML
- xml_accessor :name, :from => "NAME", :as => :cdata
- xml_accessor :books, [Book], :in => "books"
+ xml_accessor :name, :from => "NAME", :cdata => true
+ xml_accessor :books, :as => [Book]
end
To create a library and put a number of books in it we could run the following code:
book = Book.new()
@@ -64,11 +64,11 @@
class BookWithPublisher
include ROXML
xml_name :book
- xml_reader :publisher, Publisher
+ xml_reader :publisher, :as => Publisher
end
Note: In the above example, _xml_name_ annotation tells ROXML to set the element
name to "book" for mapping to XML. The default is XML element name is the class name in lowercase; "bookwithpublisher"
in this case.
@@ -76,37 +76,44 @@
== Manipulation
Extending the above examples, say you want to parse a book's page count and have it available as an Integer.
In such a case, you can extend any object with a block to manipulate it's value at parse time. For example:
- class Child
+ class Dog
include ROXML
- xml_reader :age, :attr do |val|
- Integer(val)
- end
+ xml_reader(:age, :from => '@human_years', :as => Integer) {|years| years * 7 }
end
The result of the block above is stored, rather than the actual value parsed from the document.
== Construction
-Complicated initialization may require action on multiple attributes of an object. As such, you can
-define method xml_initialize to perform initialization after instantiation and parsing, including
-causing your ROXML object to call its own constructor, as in the following:
+Object lifecycle is as follows: .from_xml is called with option initialization_args. .new,
+and thus #initialize, is called with those same args. Then the object is populated
+with the attribute values from xml. Then the #after_parse callback is called, with no arguments.
+In it you can ensure that your object initialization is complete, including initialization which
+requires more than one variable in concert.
+E.g.:
+
class Measurement
include ROXML
- xml_reader :units, :attr
- xml_reader :value, :content
+ xml_reader :units, :from => :attr
+ xml_reader :value, :from => :content
- def xml_initialize
+ def initialize(value = 0, units = 'meters')
+ to_metric
+ end
+
+ private
+ def after_parse
# xml attributes of self are already valid
- initialize(value, units)
+ to_metric
end
- def initialize(value, units)
+ def to_metric
# translate units & value into metric, for example
end
end
One important use of this approach is to make ROXML object which may or may not include an xml backing,