Browse files

Added :root option to tag method. This allows setting an object as th…

…e root element, which sets xpath to use / and sets single to true for this object.
  • Loading branch information...
1 parent a88ab23 commit 7ddc01d010043e96bd4542fa5096448b3bb1d5b5 @jnunemaker committed Jan 29, 2009
Showing with 77 additions and 34 deletions.
  1. +3 −6 examples/dashed_elements.rb
  2. +17 −16 lib/happymapper.rb
  3. +0 −1 lib/happymapper/item.rb
  4. +7 −0 spec/fixtures/family_tree.xml
  5. +50 −11 spec/happymapper_spec.rb
View
9 examples/dashed_elements.rb
@@ -7,8 +7,7 @@ module GitHub
class Commit
include HappyMapper
- tag "commit"
-
+ tag "commit", :root => true
element :url, String
element :tree, String
element :message, String
@@ -17,7 +16,5 @@ class Commit
end
end
-commits = GitHub::Commit.parse(file_contents)
-commits.each do |commit|
- puts commit.committed_date, commit.url, commit.id
-end
+commit = GitHub::Commit.parse(file_contents)
+puts commit.committed_date, commit.url, commit.id
View
33 lib/happymapper.rb
@@ -51,22 +51,24 @@ def has_many(name, type, options={})
element name, type, {:single => false}.merge(options)
end
- def tag(new_tag_name)
+ # Options:
+ # :root => Boolean, true means this is xml root
+ def tag(new_tag_name, o={})
+ options = {:root => false}.merge(o)
+ @root = options.delete(:root)
@tag_name = new_tag_name.to_s
end
def get_tag_name
@tag_name ||= to_s.downcase
end
+
+ def is_root?
+ @root
+ end
- def parse(xml, o={})
- options = {
- :single => false,
- :from_root => false,
- }.merge(o)
-
- xpath, collection = '', []
-
+ def parse(xml, o={})
+ xpath, collection, options = '', [], {:single => false}.merge(o)
doc = xml.is_a?(LibXML::XML::Node) ? xml : xml.to_libxml_doc
node = doc.respond_to?(:root) ? doc.root : doc
@@ -82,26 +84,25 @@ def parse(xml, o={})
namespace = node.namespaces.namespace.prefix + ":"
end
- xpath += doc.respond_to?(:root) ? '' : '.'
- xpath += options[:from_root] ? '/' : '//'
+ # xpath += doc.respond_to?(:root) ? '' : '.'
+ xpath += is_root? ? '/' : './/'
xpath += namespace if namespace
xpath += get_tag_name
# puts "parse: #{xpath}"
nodes = node.find(xpath)
- nodes.each do |node|
+ nodes.each do |n|
obj = new
attributes.each do |attr|
obj.send("#{attr.method_name}=",
- attr.from_xml_node(node))
+ attr.from_xml_node(n))
end
elements.each do |elem|
elem.namespace = namespace
- # puts "#{elem.method_name} - #{namespace} - #{elem.namespace}"
obj.send("#{elem.method_name}=",
- elem.from_xml_node(node))
+ elem.from_xml_node(n))
end
collection << obj
end
@@ -110,7 +111,7 @@ def parse(xml, o={})
nodes = nil
GC.start
- options[:single] ? collection.first : collection
+ options[:single] || is_root? ? collection.first : collection
end
end
end
View
1 lib/happymapper/item.rb
@@ -33,7 +33,6 @@ def from_xml_node(node)
def xpath
xpath = ''
xpath += './/' if options[:deep]
- # puts "xpath namespace: #{namespace}"
xpath += namespace if namespace
xpath += tag
# puts "xpath: #{xpath}"
View
7 spec/fixtures/family_tree.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<familytree xmlns="http://api.familysearch.org/familytree/v1" xmlns:fsapi-v1="http://api.familysearch.org/v1" version="1.0.20071213.942" statusMessage="OK" statusCode="200">
+ <persons>
+ <person version="1199378491000" modified="2008-01-03T09:41:31-07:00" id="KWQS-BBQ">
+ </person>
+ </persons>
+</familytree>
View
61 spec/happymapper_spec.rb
@@ -21,6 +21,34 @@ class Product
has_one :feature_bullets, FeatureBullet
end
+module FamilySearch
+ class Person
+ include HappyMapper
+
+ tag 'person'
+ attribute :version, String
+ attribute :modified, Time
+ attribute :id, String
+ end
+
+ class Persons
+ include HappyMapper
+
+ tag 'persons', :root => false
+ has_many :person, Person
+ end
+
+ class FamilyTree
+ include HappyMapper
+
+ tag 'familytree', :root => true
+ attribute :version, String
+ attribute :status_message, String, :tag => 'statusMessage'
+ attribute :status_code, String, :tag => 'statusCode'
+ has_one :persons, Persons
+ end
+end
+
module FedEx
class Address
include HappyMapper
@@ -85,13 +113,13 @@ class TransactionDetail
class TrackReply
include HappyMapper
-
- tag 'TrackReply'
+
+ tag 'TrackReply', :root => true
element :highest_severity, String, :tag => 'HighestSeverity'
- has_many :notifications, Notification, :tag => 'Notifications'
- has_one :tran_detail, TransactionDetail, :tab => 'TransactionDetail'
element :more_data, Boolean, :tag => 'MoreData'
+ has_many :notifications, Notification, :tag => 'Notifications'
has_many :trackdetails, TrackDetails, :tag => 'TrackDetails'
+ has_one :tran_detail, TransactionDetail, :tab => 'TransactionDetail'
end
end
@@ -156,6 +184,7 @@ class CurrentWeather
class Address
include HappyMapper
+ tag 'address', :root => true
element :street, String
element :postcode, String
element :housenumber, String
@@ -187,8 +216,7 @@ module GitHub
class Commit
include HappyMapper
- tag "commit"
-
+ tag "commit", :root => true
element :url, String
element :tree, String
element :message, String
@@ -294,7 +322,7 @@ class Foo; include HappyMapper end
end
it "should parse xml attributes into ruby objects" do
- posts = Post.parse(File.read(File.dirname(__FILE__) + '/fixtures/posts.xml'))
+ posts = Post.parse(fixture_file('posts.xml'))
posts.size.should == 20
first = posts.first
first.href.should == 'http://roxml.rubyforge.org/'
@@ -307,7 +335,7 @@ class Foo; include HappyMapper end
end
it "should parse xml elements to ruby objcts" do
- statuses = Status.parse(File.read(File.dirname(__FILE__) + '/fixtures/statuses.xml'))
+ statuses = Status.parse(fixture_file('statuses.xml'))
statuses.size.should == 20
first = statuses.first
first.id.should == 882281424
@@ -374,7 +402,7 @@ class Foo; include HappyMapper end
end
it "should parse xml that has elements with dashes" do
- commit = GitHub::Commit.parse(fixture_file('commit.xml')).first
+ commit = GitHub::Commit.parse(fixture_file('commit.xml'))
commit.message.should == "move commands.rb and helpers.rb into commands/ dir"
commit.url.should == "http://github.com/defunkt/github-gem/commit/c26d4ce9807ecf57d3f9eefe19ae64e75bcaaa8b"
commit.id.should == "c26d4ce9807ecf57d3f9eefe19ae64e75bcaaa8b"
@@ -410,7 +438,7 @@ class Foo; include HappyMapper end
end
it "should parse xml with multiple namespaces" do
- track = FedEx::TrackReply.parse(fixture_file('multiple_namespaces.xml'), :single => true, :from_root => true)
+ track = FedEx::TrackReply.parse(fixture_file('multiple_namespaces.xml'))
track.highest_severity.should == 'SUCCESS'
track.more_data.should be_false
notification = track.notifications.first
@@ -449,5 +477,16 @@ class Foo; include HappyMapper end
last_event.address.state.should == 'FL'
last_event.address.zip.should == '327506398'
track.tran_detail.cust_tran_id.should == '20090102-111321'
- end
+ end
+
+ xit "should parse family search xml" do
+ tree = FamilySearch::FamilyTree.parse(fixture_file('family_tree.xml'))
+ tree.version.should == '1.0.20071213.942'
+ tree.status_message.should == 'OK'
+ tree.status_code.should == '200'
+ # tree.people.size.should == 1
+ # tree.people.first.version.should == '1199378491000'
+ # tree.people.first.modified.should == Time.utc(2008, 1, 3, 16, 41, 31) # 2008-01-03T09:41:31-07:00
+ # tree.people.first.id.should == 'KWQS-BBQ'
+ end
end

0 comments on commit 7ddc01d

Please sign in to comment.