Mapricot

XML to object mapper with an interface similar to ActiveRecord associations.

Install

sudo gem install mapricot

Example Usage

Super Simple

require 'mapricot'

simple_xml = %(
  <user>
    <id>1</name>
    <name>Bob</name>
    <pet>cat</pet>
    <pet>dog</pet>
  </user>
)

class User < Mapricot::Base
  has_one   :id,    :integer
  has_one   :name,  :string
  has_many  :pets,  :string
end

user = User.new(:xml => simple_xml)
puts user.id                # => 1
puts user.id.class          # => Fixnum
puts user.name              # => Bob
puts user.pets.class        # => Array
puts user.pets.join(", ")   # => cat, dog

A little more realistic

require 'mapricot'

xml = %(
  <user>
    <id>2</name>
    <name>Sally</name>
    <location code="ny123">
      <city>New York</city>
      <state>NY</state>
    </location>
    <hobby>
      <description>Skiing</description>
      <number_of_years>2</number_of_years>
    </hobby>
    <hobby>
      <description>Hiking</description>
      <number_of_years>3</number_of_years>
    </hobby>
  </user>
)

class User < Mapricot::Base
  has_one   :id,        :integer
  has_one   :name       # Tag type will default to :string
  has_many  :pets
  has_one   :location,  :xml
  has_many  :hobbies,   :xml
end

class Location < Mapricot::Base
  has_attribute :code
  has_one       :city
  has_one       :state
end

class Hobby < Mapricot::Base
  has_one :description,     :string
  has_one :number_of_years, :integer
end

user = User.new(:xml => xml)
puts user.name            # => Sally
puts user.pets.inspect    # => []
puts user.location.class  # => Location
puts user.location.city   # => New York
puts user.location.state  # => NY
puts user.location.code   # => ny123
puts user.hobbies.class         # => Array
puts user.hobbies.first.class   # => Hobby

user.hobbies.each do |hobby|
  puts "#{hobby.description} for #{hobby.number_of_years} years"
end
# => Skiing for 2 years
# => Hiking for 3 years

Usage, TODO: fix this garbage

Your classes should inherit from Mapricot::Base, which provides the class methods

  • has_one(name, type, opts = {})

  • has_many(name, type, opts = {})

  • has_attribute(name)

When you instantiate a Mapricot::Base object, you can pass it a string of xml:

class MapMe < Mapricot::Base
end

MapMe.new :xml => "<some_stuff>...</some_stuff>"

Or a url:

MapMe.new :url => "http://some_url"

Credits

Named after why the luck stiff’s Hpricot, which made this possible.

Copyright © 2009 Lou Zell, released under the MIT license