34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
# File 'lib/xmlmapping.rb', line 34
def initialize(input)
if input.respond_to? :to_str
root = REXML::Document.new(input).root
elsif input.respond_to?(:node_type) && input.node_type == :document
root = input.root
elsif input.respond_to?(:node_type) && input.node_type == :element
root = input
else
raise "Invalid input: #{input}"
end
namespace = self.class.default_namespace
attributes = self.class.attributes
elements = self.class.elements
text_attribute = self.class.text_attribute
if !text_attribute.nil?
name = text_attribute[0]
options = text_attribute[1]
value = root.text
if options.has_key? :transform
value = options[:transform].call(value)
end
instance_variable_set("@#{name}", value)
else
elements.select { |k, v|
v[:cardinality] == :many
}.each { |k, v|
instance_variable_set("@#{v[:attribute]}", [])
}
root.each_element { |e|
if e.namespace == namespace && elements.has_key?(e.name.to_sym)
options = elements[e.name.to_sym]
if options.has_key? :type
value = options[:type].new(e)
else
value = e.text
end
if options.has_key? :transform
value = options[:transform].call(value)
end
attribute = options[:attribute]
existing = instance_variable_get("@#{attribute}")
case options[:cardinality]
when :one
raise "Found more than one #{e.name}" if !existing.nil?
instance_variable_set("@#{attribute}", value)
when :many
existing << value
end
end
}
end
root.attributes.each_attribute { |a|
if a.namespace == namespace && attributes.has_key?(a.name.to_sym)
options = attributes[a.name.to_sym]
value = a.value
if options.has_key? :transform
value = options[:transform].call(value)
end
instance_variable_set("@#{a.name}", value)
end
}
end
|