require "lib/roxml" class Muffins include ROXML xml_reader(:count, :from => 'bakers_dozens') {|val| val.to_i * 13 } end class MuffinsWithStackedBlocks include ROXML xml_reader(:count, :from => 'bakers_dozens', :as => Integer) {|val| val * 13 } end class Numerology include ROXML xml_reader :predictions, :as => {:key => '@number', :value => '@meaning'} do |k, v| [Integer(k), v] end end class Contributor include ROXML xml_reader :role, :from => :attr xml_reader :name end class WriteableContributor include ROXML xml_accessor :role, :from => :attr xml_accessor :name end class Book include ROXML xml_accessor :isbn, :from => '@ISBN' xml_reader :title xml_reader :description, :cdata => true xml_reader :author xml_accessor :pages, :from => 'pagecount', :as => Integer end class BookWithRequired include ROXML xml_accessor :isbn, :from => '@ISBN', :required => true xml_reader :title, :required => true xml_reader :contributors, :as => [Contributor], :in => 'contributor_array', :required => true xml_reader :contributor_hash, :as => {:key => '@role', :value => '@name'}, :from => 'contributor', :in => 'contributor_hash', :required => true end class BookWithAttrFrom include ROXML xml_accessor :isbn, :from => '@ISBN' end class BookWithWrappedAttr include ROXML xml_name :book xml_accessor :isbn, :from => '@ISBN', :in => 'ids' end class Measurement include ROXML xml_reader :units, :from => :attr xml_reader :value, :from => :content, :as => Float def initialize(value = 0, units = 'pixels') @value = Float(value) @units = units.to_s normalize_hundredths end def to_s "#{value} #{units}" end def ==(other) other.units == @units && other.value == @value end private def after_parse normalize_hundredths end def normalize_hundredths if @units.starts_with? 'hundredths-' @value /= 100 @units = @units.split('hundredths-')[1] end end end class BookWithDepth include ROXML xml_reader :isbn, :from => '@ISBN' xml_reader :title xml_reader :description, :cdata => true xml_reader :author xml_reader :depth, :as => Measurement end class Author include ROXML xml_reader :role, :from => :attr xml_reader :text, :from => :content end class BookWithAuthors include ROXML xml_name :book xml_reader :isbn, :from => '@ISBN' xml_reader :title xml_reader :description, :cdata => true xml_reader :authors, :as => [] end class BookWithAuthorTextAttribute include ROXML xml_name :book xml_reader :isbn, :from => '@ISBN' xml_reader :title xml_reader :description, :cdata => true xml_reader :author, :as => Author end class BookWithContributions include ROXML xml_name :book xml_reader :isbn, :from => :attr xml_reader :title xml_reader :description xml_reader :contributions, :as => [Contributor], :from => 'contributor', :in => "contributions" end class BookWithContributors include ROXML xml_name :book xml_reader :isbn, :from => :attr xml_reader :title xml_reader :description xml_reader :contributors, :as => [Contributor] end class WriteableBookWithContributors include ROXML xml_name :book xml_accessor :isbn, :from => :attr xml_accessor :title xml_accessor :description xml_accessor :contributors, :as => [Contributor] end class NamelessBook include ROXML xml_reader :isbn, :from => :attr xml_reader :title xml_reader :description xml_reader :contributors, :as => [Contributor] end class Publisher include ROXML xml_reader :name end class BookWithPublisher include ROXML xml_reader :book xml_reader :isbn, :from => :attr xml_reader :title xml_reader :description xml_reader :publisher, :as => Publisher end class BookPair include ROXML xml_reader :isbn, :from => :attr xml_reader :title xml_reader :description xml_reader :author xml_reader :book, :as => Book end class Library include ROXML xml_reader :name xml_reader :books, :as => [BookWithContributions] end class UppercaseLibrary include ROXML xml_name :library xml_reader :name, :from => 'NAME' xml_reader :books, :as => [BookWithContributions], :from => 'BOOK' end class LibraryWithBooksOfUnderivableName include ROXML xml_accessor :name xml_reader :novels, :as => [NamelessBook] end class NodeWithNameConflicts include ROXML xml_name :node xml_reader :content xml_reader :name end class NodeWithAttrNameConflicts include ROXML xml_name :node xml_reader :content, :from => '@content' xml_reader :name, :from => '@name' end class Person include ROXML xml_accessor :age, :from => :attr, :else => 21 xml_accessor :name, :from => :content, :else => 'Unknown' def self.blank returning new do |instance| instance.age = 21 instance.name = 'Unknown' end end end class PersonWithMother include ROXML xml_name :person xml_reader :name xml_reader :mother, :as => PersonWithMother, :from => 'mother' end class PersonWithGuardedMother include ROXML xml_name :person xml_reader :name xml_reader :mother, :as => PersonWithGuardedMother, :from => :person, :in => :mother end class PersonWithMotherOrMissing include ROXML xml_reader :age, :from => :attr, :else => 21 xml_reader :name, :else => 'Anonymous' xml_reader :mother,:as => PersonWithMotherOrMissing, :else => Person.blank end