Created
August 29, 2011 16:31
-
-
Save jpshackelford/1178773 to your computer and use it in GitHub Desktop.
Sample Code for ROXML Text Node Factory
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'rubygems' | |
require 'roxml' | |
xml = ' | |
<library> | |
<name>Fullerton Public</name> | |
<phoneNumber>000-000-000</phoneNumber> | |
<media> | |
<item> | |
<medium>cassette-tape</medium> | |
<title>The Story About Ping</title> | |
<readBy>A. Reader</readBy> | |
</item> | |
<item> | |
<medium>book</medium> | |
<title>The Story About Ping</title> | |
<binding>hardcover</binding> | |
</item> | |
</media> | |
</library> | |
' | |
class Library | |
include ROXML | |
xml_convention do |s| | |
c = s.camelcase | |
c[0..0].to_s.downcase + c[1..-1].to_s | |
end | |
xml_accessor :name | |
xml_accessor :phone_number | |
end | |
lib = Library.from_xml( xml ) # pass an IO or String containing the XML | |
puts lib.to_xml | |
class Book | |
include ROXML | |
xml_accessor :title | |
xml_accessor :author | |
end | |
class Library | |
xml_accessor :books, :in => :books, | |
:as => [Book] | |
end | |
lib = Library.new | |
lib.name = 'Fullerton Public' | |
lib.books = [] | |
a_book = Book.new | |
a_book.title = 'The Story About Ping' | |
a_book.author = 'Marjorie Flack' | |
lib.books << a_book | |
puts lib.to_xml | |
puts Library.from_xml( lib.to_xml.to_s ).books.first.title | |
class Medium | |
include ROXML | |
class << self | |
def register(medium_id = nil, a_class = self) | |
registry.store(medium_id || id_from_class, a_class) | |
end | |
def id_from_class | |
demod = ActiveSupport::Inflector.demodulize(self.name) | |
underscored = ActiveSupport::Inflector.underscore(demod) | |
dasherized = ActiveSupport::Inflector.dasherize(underscored) | |
end | |
def class_for(medium_id) | |
registry[medium_id] | |
end | |
def registry | |
unless Medium.instance_variable_defined?(:@registry) | |
Medium.instance_variable_set(:@registry, { }) | |
end | |
Medium.instance_variable_get(:@registry) | |
end | |
private :registry | |
alias __original_from_xml from_xml | |
def from_xml(xml, *args) | |
if self == Medium | |
xml_node = ROXML::XML::Node.from(xml) | |
if xml_node.nil? | |
raise "Bad xml for action:\n\t#{xml}" | |
end | |
medium_id = xml_node.xpath('medium').first.text.strip | |
medium_class = @registry[medium_id] if defined?(@registry) | |
unless medium_class.nil? | |
medium_class.from_xml(xml_node, *args) | |
else | |
$stderr.puts "WARN: no medium for #{medium_id}." | |
__original_from_xml(xml, *args) | |
end | |
else | |
__original_from_xml(xml, *args) | |
end | |
end | |
end # class methods | |
xml_name 'medium' # even in subclasses | |
xml_convention do |s| | |
c = s.camelcase | |
c[0..0].to_s.downcase + c[1..-1].to_s | |
end | |
xml_accessor :title | |
xml_accessor :author | |
end | |
class CassetteTape < Medium | |
xml_accessor :read_by | |
end | |
self.class.send(:remove_const, :Book ) | |
class Book < Medium | |
xml_accessor :binding | |
end | |
class Library | |
xml_accessor :media, | |
:from => 'item', | |
:in => 'media', | |
:as => [Medium] | |
end | |
CassetteTape.register | |
Book.register | |
puts Medium.send(:registry).inspect | |
lib = Library.from_xml(xml) | |
lib.media.each do |item| | |
puts "#{item.title} (#{item.class})" | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment