| Module | ROXML::ROXML_Class |
| In: |
lib/roxml.rb
|
This class defines the annotation methods that are mixed into your Ruby classes for XML mapping information and behavior.
See xml_name, xml_construct, xml, xml_reader and xml_accessor for available annotations.
Creates a new Ruby object from XML using mapping information annotated in the class.
The input data is either an XML::Node or a String representing the XML document.
Example
book = Book.parse(File.read("book.xml"))
or
book = Book.parse("<book><name>Beyond Java</name></book>")
See also: xml_construct
Declares an accesser to a certain xml element, whether an attribute, a node, or a typed collection of nodes
All type arguments may be used as the type argument to indicate just type, or used as :from, pointing to a xml name to indicate both type and attribute name. Also, any type may be passed via an array to indicate that multiple instances of the object should be returned as an array.
Declare an accessor that represents an XML attribute.
Example:
class Book xml_reader :isbn, :attr => "ISBN" # 'ISBN' is used to specify :from xml_accessor :title, :attr # :from defaults to :title end
To map:
<book ISBN="0974514055" title="Programming Ruby: the pragmatic programmers' guide" />
The default type, if none is specified. Declares an accessor that represents a text node from XML.
Example:
class Book xml :author, false, :text => 'Author' xml_accessor :description, :text, :as => :cdata xml_reader :title end
To map:
<book> <title>Programming Ruby: the pragmatic programmers' guide</title> <description><![CDATA[Probably the best Ruby book out there]]></description> <Author>David Thomas</author> </book>
Likewise, a number of :text node values can be collected in an array like so:
Example:
class Library xml_reader :books, [:text], :in => 'books' end
To map:
<library>
<books>
<book>To kill a mockingbird</book>
<book>House of Leaves</book>
<book>Gödel, Escher, Bach</book>
</books>
</library>
A special case of :text, this refers to the content of the current node, rather than a sub-node
Example:
class Contributor xml_reader :name, :content xml_reader :role, :attr end
To map:
<contributor role="editor">James Wick</contributor>
Somewhere between the simplicity of a :text/:attr mapping, and the complexity of a full Object/Type mapping, lies the Hash mapping. It serves in the case where you have a collection of key-value pairs represented in your xml. You create a hash declaration by passing a hash mapping as the type argument. A few examples:
For xml such as this:
<dictionary>
<definitions>
<definition dt="quaquaversally"
dd="adjective: (of a geological formation) sloping downward from the center in all directions." />
<definition dt="tergiversate"
dd="To use evasions or ambiguities; equivocate." />
</definitions>
</dictionary>
You can use the :attrs key in you has with a [:key, :value] name array:
xml_reader :definitions, {:attrs => ['dt', 'dd']}, :in => :definitions
For xml such as this:
<dictionary>
<definition>
<word/>
<meaning/>
</definition>
<definition>
<word/>
<meaning/>
</definition>
</dictionary>
You can individually declare your key and value names:
xml_reader :definitions, {:key => 'word',
:value => 'meaning'}
For xml such as this:
<dictionary>
<definition word="quaquaversally">adjective: (of a geological formation) sloping downward from the center in all directions.</definition>
<definition word="tergiversate">To use evasions or ambiguities; equivocate.</definition>
</dictionary>
You can individually declare the key and value, but with the attr, you need to provide both the type and name of that type (i.e. {:attr => :word}), because omitting the type will result in ROXML defaulting to :text
xml_reader :definitions, {:key => {:attr => 'word'},
:value => :content}
For xml such as this:
<dictionary>
<quaquaversally>adjective: (of a geological formation) sloping downward from the center in all directions.</quaquaversally>
<tergiversate>To use evasions or ambiguities; equivocate.</tergiversate>
</dictionary>
You can pick up the node names (e.g. quaquaversally) using the :name keyword:
xml_reader :definitions, {:key => :name,
:value => :content}
Declares an accessor that represents another ROXML class as child XML element (one-to-one or composition) or array of child elements (one-to-many or aggregation) of this type. Default is one-to-one. Use :array option for one-to-many, or simply pass the class in an array.
Composition example:
<book>
<publisher>
<name>Pragmatic Bookshelf</name>
</publisher>
</book>
Can be mapped using the following code:
class Book
xml_reader :publisher, Publisher
end
Aggregation example:
<library> <books> <book/> <book/> </books> </library>
Can be mapped using the following code:
class Library xml_reader :books, [Book], :in => "books" end
If you don‘t have the <books> tag to wrap around the list of <book> tags:
<library> <name>Ruby books</name> <book/> <book/> </library>
You can skip the wrapper argument:
xml_reader :books, [Book]
For readonly attributes, you may pass a block which manipulates the associated parsed value.
class Muffins
include ROXML
xml_reader :count, :from => 'bakers_dozens' {|val| val.to_i * 13 }
end
For hash types, the block recieves the key and value as arguments, and they should be returned as an array of [key, value]
On parse, call the target object‘s initialize function with the listed arguments
Sets the name of the XML element that represents this class. Use this to override the default lowercase class name.
Example:
class BookWithPublisher xml_name :book end
Without the xml_name annotation, the XML mapped tag would have been "bookwithpublisher".