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,