README.rdoc in Empact-roxml-2.4.3 vs README.rdoc in Empact-roxml-2.5.1
- old
+ new
@@ -12,40 +12,40 @@
ROXML, you can annotate the Ruby classes as follows:
class Book
include ROXML
- xml_reader :isbn, :attr => "ISBN" # attribute with name 'ISBN'
- xml_reader :title
- xml_reader :description, :as => :cdata # text node with cdata protection
- xml_reader :author
+ xml_accessor :isbn, :from => "@ISBN" # attribute with name 'ISBN'
+ xml_accessor :title
+ xml_accessor :description, :cdata => true # text node with cdata protection
+ xml_accessor :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] # by default roxml searches for books for in <book> child nodes, then, if none are present, in ./books/book children
end
To create a library and put a number of books in it we could run the following code:
- book = Book.new()
+ book = Book.new
book.isbn = "0201710897"
book.title = "The PickAxe"
book.description = "Best Ruby book out there!"
book.author = "David Thomas, Andrew Hunt, Dave Thomas"
- lib = Library.new()
+ lib = Library.new
lib.name = "Favorite Books"
- lib << book
+ lib.books = [book]
To save this information to an XML file:
- File.open("library.xml", "w") do |f|
- lib.to_xml.write(f, 0)
- end
+ doc = ROXML::XML::Document.new
+ doc.root = lib.to_xml
+ doc.save("library.xml")
To later populate the library object from the XML file:
lib = Library.from_xml(File.read("library.xml"))
@@ -60,15 +60,26 @@
</publisher>
</book>
can be mapped using the following code:
+ class Publisher
+ include ROXML
+
+ xml_accessor :name
+
+ # other important functionality
+ end
+
class BookWithPublisher
include ROXML
- xml_name :book
- xml_reader :publisher, Publisher
+ xml_name 'book'
+ xml_reader :publisher, :as => Publisher
+
+ # or, alternatively, if no class is needed to hang functionality on:
+ # xml_reader :publisher, :from => 'name', :in => '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 +87,48 @@
== 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 life-cycle is as follows: .from_xml is called with a first argument representing the xml
+in file, string, or path form, and with optional initialization_args following.
+Firt .new and thus #initialize, is called with those same initialization_args, or no args if none
+are present. Then the object is populated with the attribute values from xml. Then the
+#after_parse callback is called, with no arguments.
+
+In #after_parse 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,