public
Fork of Empact/roxml
Description: ROXML is a module for binding Ruby classes to XML. It supports custom mapping and bidirectional marshalling between Ruby and XML using annotation-style class methods. ROXML supports the LibXML and REXML XML processors.
Homepage: http://roxml.rubyforge.org/
Clone URL: git://github.com/yob/roxml.git
roxml /
name age message
file .gitignore Wed Aug 27 23:54:00 -0700 2008 Ignore docs [Empact]
file CHANGELOG Fri Oct 24 06:59:55 -0700 2008 Duplicate the default value to avoid carrying o... [Empact]
file MIT-LICENSE Fri Sep 12 21:45:27 -0700 2008 More doc cleanup [Empact]
file README.rdoc Thu Oct 02 03:15:26 -0700 2008 v2.1 A few final fixes... [Empact]
file Rakefile Thu Oct 02 03:06:59 -0700 2008 Simply parser selection by referencing ROXML::X... [Empact]
file TODO Sat Sep 20 01:22:20 -0700 2008 A few todos for 2.1 [Empact]
directory html/ Sun Sep 24 09:20:20 -0700 2006 1.1 release with XML text with attributes and m... [Zak Mandhro]
directory lib/ Fri Oct 24 06:59:55 -0700 2008 Duplicate the default value to avoid carrying o... [Empact]
directory rails_plugin/ Mon Jul 03 06:34:51 -0700 2006 Added support for Ruby on Rails plugin release. [Zak Mandhro]
file roxml.gemspec Mon Oct 27 19:36:54 -0700 2008 Update the gemspec to trigger the generation of... [yob]
directory test/ Fri Oct 24 07:00:42 -0700 2008 fix a merge errror [yob]
README.rdoc

ROXML Ruby Object to XML mapping library. For more information visit roxml.rubyforge.org

Quick Start Guide

This is a short usage example. See ROXML::ROXML_Class and packaged test cases for more information.

Basic Mapping

Consider an XML document representing a Library containing a number of Books. You can map this structure to Ruby classes that provide addition useful behavior. With 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
  end

  class Library
    include ROXML

    xml_accessor :name, :from => "NAME", :as => :cdata
    xml_accessor :books, [Book], :in => "books"
  end

To create a library and put a number of books in it we could run the following code:

  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.name = "Favorite Books"
  lib << book

To save this information to an XML file:

  File.open("library.xml", "w") do |f|
    lib.to_xml.write(f, 0)
  end

To later populate the library object from the XML file:

  lib = Library.parse(File.read("library.xml"))

Similarly, to do a one-to-one mapping between XML objects, such as book and publisher, you would add a reference to another ROXML class. For example:

  <book isbn="0974514055">
    <title>Programming Ruby - 2nd Edition</title>
    <description>Second edition of the great book.</description>
    <publisher>
      <name>Pragmatic Bookshelf</name>
    </publisher>
  </book>

can be mapped using the following code:

  class BookWithPublisher
    include ROXML

    xml_name :book
    xml_reader :publisher, 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.

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
    include ROXML

    xml_reader :age, :attr do |val|
      Integer(val)
    end
  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 use xml_construct to cause your ROXML object to call its own constructor. For example:

  class Measurement
    include ROXML

    xml_reader :units, :attr
    xml_reader :value, :content

    xml_construct :value, :units

    def initialize(value, units)
      # translate units & value into metric, for example
    end
  end

Will, on parse, read all listed xml attributes (units and value, in this case), then call initialize with the arguments listed after the xml_construct call.

Selecting a parser

By default, ROXML will use LibXML if it is available, or otherwise REXML. If you’d like to explicitly require one or the other, you may do the following:

  module ROXML
    XML_PARSER = 'libxml' # or 'rexml'
  end
  require 'roxml'

For more information on available annotations, see ROXML::ROXML_Class