UnderpantsGnome-sax-machine 0.0.13 → 0.0.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -5,9 +5,9 @@ module SAXMachine
|
|
|
5
5
|
attr_reader :name
|
|
6
6
|
|
|
7
7
|
def initialize(name, options)
|
|
8
|
-
@name
|
|
9
|
-
@class
|
|
10
|
-
@as
|
|
8
|
+
@name = name.to_s
|
|
9
|
+
@class = options[:class]
|
|
10
|
+
@as = options[:as].to_s
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
def handler
|
|
@@ -30,4 +30,4 @@ module SAXMachine
|
|
|
30
30
|
end
|
|
31
31
|
|
|
32
32
|
end
|
|
33
|
-
end
|
|
33
|
+
end
|
|
@@ -5,6 +5,7 @@ module SAXMachine
|
|
|
5
5
|
class SAXConfig
|
|
6
6
|
def initialize
|
|
7
7
|
@top_level_elements = []
|
|
8
|
+
@complex_elements = []
|
|
8
9
|
@collection_elements = []
|
|
9
10
|
end
|
|
10
11
|
|
|
@@ -12,10 +13,18 @@ module SAXMachine
|
|
|
12
13
|
@top_level_elements << ElementConfig.new(name, options)
|
|
13
14
|
end
|
|
14
15
|
|
|
16
|
+
def add_complex_element(name, options)
|
|
17
|
+
@complex_elements << ElementConfig.new(name, options)
|
|
18
|
+
end
|
|
19
|
+
|
|
15
20
|
def add_collection_element(name, options)
|
|
16
21
|
@collection_elements << CollectionConfig.new(name, options)
|
|
17
22
|
end
|
|
18
23
|
|
|
24
|
+
def complex_config(name)
|
|
25
|
+
@complex_elements.detect { |ce| ce.name.to_s == name.to_s }
|
|
26
|
+
end
|
|
27
|
+
|
|
19
28
|
def collection_config(name)
|
|
20
29
|
@collection_elements.detect { |ce| ce.name.to_s == name.to_s }
|
|
21
30
|
end
|
|
@@ -33,6 +42,5 @@ module SAXMachine
|
|
|
33
42
|
element_config.attrs_match?(attrs)
|
|
34
43
|
end
|
|
35
44
|
end
|
|
36
|
-
|
|
37
45
|
end
|
|
38
|
-
end
|
|
46
|
+
end
|
|
@@ -1,37 +1,44 @@
|
|
|
1
1
|
require "nokogiri"
|
|
2
2
|
|
|
3
3
|
module SAXMachine
|
|
4
|
-
|
|
5
4
|
def self.included(base)
|
|
6
5
|
base.extend ClassMethods
|
|
7
6
|
end
|
|
8
|
-
|
|
7
|
+
|
|
9
8
|
def parse(xml_text)
|
|
10
9
|
sax_handler = SAXHandler.new(self)
|
|
11
10
|
parser = Nokogiri::XML::SAX::Parser.new(sax_handler)
|
|
12
11
|
parser.parse(xml_text)
|
|
13
12
|
self
|
|
14
13
|
end
|
|
15
|
-
|
|
16
|
-
module ClassMethods
|
|
17
14
|
|
|
15
|
+
module ClassMethods
|
|
18
16
|
def parse(xml_text)
|
|
19
17
|
new.parse(xml_text)
|
|
20
18
|
end
|
|
21
|
-
|
|
19
|
+
|
|
22
20
|
def element(name, options = {})
|
|
23
21
|
options[:as] ||= name
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
22
|
+
|
|
23
|
+
unless options[:class]
|
|
24
|
+
sax_config.add_top_level_element(name, options)
|
|
25
|
+
else
|
|
26
|
+
sax_config.add_complex_element(name, options)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# We only want to insert the getter and setter if they haven't been
|
|
30
|
+
# defined elsewhere. This is how we allow custom parsing behavior. So you
|
|
31
|
+
# could define the setter and have it parse the string into a date or
|
|
32
|
+
# whatever. However, if the getter or setter is defined by a superclass,
|
|
33
|
+
# we go ahead and overwrite it. This allows use to still access elements
|
|
34
|
+
# with names like "id".
|
|
35
|
+
attr_reader options[:as] unless instance_methods(false).include?(options[:as].to_s)
|
|
36
|
+
attr_writer options[:as] unless instance_methods(false).include?("#{options[:as]}=")
|
|
31
37
|
end
|
|
32
|
-
|
|
38
|
+
|
|
33
39
|
def elements(name, options = {})
|
|
34
40
|
options[:as] ||= name
|
|
41
|
+
|
|
35
42
|
if options[:class]
|
|
36
43
|
sax_config.add_collection_element(name, options)
|
|
37
44
|
else
|
|
@@ -40,23 +47,23 @@ module SAXMachine
|
|
|
40
47
|
#{options[:as]} << value
|
|
41
48
|
end
|
|
42
49
|
SRC
|
|
50
|
+
|
|
43
51
|
sax_config.add_top_level_element(name, options.merge(:collection => true))
|
|
44
52
|
end
|
|
45
|
-
|
|
53
|
+
|
|
46
54
|
if !instance_methods.include?(options[:as].to_s)
|
|
47
|
-
|
|
55
|
+
class_eval <<-SRC
|
|
48
56
|
def #{options[:as]}
|
|
49
57
|
@#{options[:as]} ||= []
|
|
50
58
|
end
|
|
51
59
|
SRC
|
|
52
60
|
end
|
|
53
|
-
|
|
61
|
+
|
|
54
62
|
attr_writer options[:as] unless instance_methods.include?("#{options[:as]}=")
|
|
55
63
|
end
|
|
56
|
-
|
|
64
|
+
|
|
57
65
|
def sax_config
|
|
58
66
|
@sax_config ||= SAXConfig.new
|
|
59
67
|
end
|
|
60
68
|
end
|
|
61
|
-
|
|
62
|
-
end
|
|
69
|
+
end
|
|
@@ -1,28 +1,28 @@
|
|
|
1
1
|
module SAXMachine
|
|
2
2
|
class SAXConfig
|
|
3
|
-
|
|
4
3
|
class ElementConfig
|
|
5
4
|
attr_reader :name, :setter
|
|
6
|
-
|
|
5
|
+
|
|
7
6
|
def initialize(name, options)
|
|
8
|
-
@name
|
|
9
|
-
|
|
7
|
+
@name = name.to_s
|
|
8
|
+
@class = options[:class]
|
|
9
|
+
|
|
10
10
|
if options.has_key?(:with)
|
|
11
11
|
# for faster comparisons later
|
|
12
12
|
@with = options[:with].to_a.flatten.collect {|o| o.to_s}
|
|
13
13
|
else
|
|
14
14
|
@with = nil
|
|
15
15
|
end
|
|
16
|
-
|
|
16
|
+
|
|
17
17
|
if options.has_key?(:value)
|
|
18
18
|
@value = options[:value].to_s
|
|
19
19
|
else
|
|
20
20
|
@value = nil
|
|
21
21
|
end
|
|
22
|
-
|
|
22
|
+
|
|
23
23
|
@as = options[:as]
|
|
24
24
|
@collection = options[:collection]
|
|
25
|
-
|
|
25
|
+
|
|
26
26
|
if @collection
|
|
27
27
|
@setter = "add_#{options[:as]}"
|
|
28
28
|
else
|
|
@@ -33,7 +33,7 @@ module SAXMachine
|
|
|
33
33
|
def value_from_attrs(attrs)
|
|
34
34
|
attrs.index(@value) ? attrs[attrs.index(@value) + 1] : nil
|
|
35
35
|
end
|
|
36
|
-
|
|
36
|
+
|
|
37
37
|
def attrs_match?(attrs)
|
|
38
38
|
if @with
|
|
39
39
|
@with == (@with & attrs)
|
|
@@ -41,15 +41,18 @@ module SAXMachine
|
|
|
41
41
|
true
|
|
42
42
|
end
|
|
43
43
|
end
|
|
44
|
-
|
|
44
|
+
|
|
45
45
|
def has_value_and_attrs_match?(attrs)
|
|
46
46
|
!@value.nil? && attrs_match?(attrs)
|
|
47
47
|
end
|
|
48
|
-
|
|
48
|
+
|
|
49
49
|
def collection?
|
|
50
50
|
@collection
|
|
51
51
|
end
|
|
52
|
+
|
|
53
|
+
def handler
|
|
54
|
+
SAXHandler.new(@class.new) if @class
|
|
55
|
+
end
|
|
52
56
|
end
|
|
53
|
-
|
|
54
57
|
end
|
|
55
|
-
end
|
|
58
|
+
end
|
|
@@ -7,10 +7,13 @@ module SAXMachine
|
|
|
7
7
|
def initialize(object)
|
|
8
8
|
@object = object
|
|
9
9
|
@parsed_configs = {}
|
|
10
|
+
@parsed_complex_configs = {}
|
|
10
11
|
end
|
|
11
12
|
|
|
12
13
|
def characters(string)
|
|
13
|
-
if
|
|
14
|
+
if parsing_complex?
|
|
15
|
+
@complex_handler.characters(string)
|
|
16
|
+
elsif parsing_collection?
|
|
14
17
|
@collection_handler.characters(string)
|
|
15
18
|
elsif @element_config
|
|
16
19
|
@value << string
|
|
@@ -25,9 +28,16 @@ module SAXMachine
|
|
|
25
28
|
@name = name
|
|
26
29
|
@attrs = attrs
|
|
27
30
|
|
|
28
|
-
if
|
|
31
|
+
if parsing_complex?
|
|
32
|
+
@complex_handler.start_element(@name, @attrs)
|
|
33
|
+
|
|
34
|
+
elsif parsing_collection?
|
|
29
35
|
@collection_handler.start_element(@name, @attrs)
|
|
30
36
|
|
|
37
|
+
elsif @complex_config = sax_config.complex_config(@name)
|
|
38
|
+
@complex_handler = @complex_config.handler
|
|
39
|
+
@complex_handler.start_element(@name, @attrs)
|
|
40
|
+
|
|
31
41
|
elsif @collection_config = sax_config.collection_config(@name)
|
|
32
42
|
@collection_handler = @collection_config.handler
|
|
33
43
|
@collection_handler.start_element(@name, @attrs)
|
|
@@ -42,7 +52,15 @@ module SAXMachine
|
|
|
42
52
|
end
|
|
43
53
|
|
|
44
54
|
def end_element(name)
|
|
45
|
-
if
|
|
55
|
+
if parsing_complex? && @complex_config.name == name && !parsed_complex_config?
|
|
56
|
+
complex_mark_as_parsed
|
|
57
|
+
@object.send(@complex_config.setter, @complex_handler.object)
|
|
58
|
+
reset_current_complex
|
|
59
|
+
|
|
60
|
+
elsif parsing_complex? && !parsed_complex_config?
|
|
61
|
+
@complex_handler.end_element(name)
|
|
62
|
+
|
|
63
|
+
elsif parsing_collection? && @collection_config.name == name
|
|
46
64
|
@object.send(@collection_config.accessor) << @collection_handler.object
|
|
47
65
|
reset_current_collection
|
|
48
66
|
|
|
@@ -61,6 +79,10 @@ module SAXMachine
|
|
|
61
79
|
!@value.nil? && !@value.empty?
|
|
62
80
|
end
|
|
63
81
|
|
|
82
|
+
def parsing_complex?
|
|
83
|
+
!@complex_handler.nil?
|
|
84
|
+
end
|
|
85
|
+
|
|
64
86
|
def parsing_collection?
|
|
65
87
|
!@collection_handler.nil?
|
|
66
88
|
end
|
|
@@ -97,15 +119,28 @@ module SAXMachine
|
|
|
97
119
|
@parsed_configs[element_config]
|
|
98
120
|
end
|
|
99
121
|
|
|
122
|
+
def complex_mark_as_parsed
|
|
123
|
+
@parsed_complex_configs[@complex_config] = true
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def parsed_complex_config?
|
|
127
|
+
@parsed_complex_configs[@complex_config]
|
|
128
|
+
end
|
|
129
|
+
|
|
100
130
|
def reset_current_collection
|
|
101
131
|
@collection_handler = nil
|
|
102
132
|
@collection_config = nil
|
|
103
133
|
end
|
|
104
134
|
|
|
135
|
+
def reset_current_complex
|
|
136
|
+
@complex_handler = nil
|
|
137
|
+
@complex_config = nil
|
|
138
|
+
end
|
|
139
|
+
|
|
105
140
|
def reset_current_tag
|
|
106
|
-
@name
|
|
107
|
-
@attrs
|
|
108
|
-
@value
|
|
141
|
+
@name = nil
|
|
142
|
+
@attrs = nil
|
|
143
|
+
@value = nil
|
|
109
144
|
@element_config = nil
|
|
110
145
|
end
|
|
111
146
|
|
|
@@ -113,4 +148,4 @@ module SAXMachine
|
|
|
113
148
|
@object.class.sax_config
|
|
114
149
|
end
|
|
115
150
|
end
|
|
116
|
-
end
|
|
151
|
+
end
|
|
@@ -28,7 +28,7 @@ describe "SAXMachine" do
|
|
|
28
28
|
document.title = "Title"
|
|
29
29
|
document.title.should == "Title **"
|
|
30
30
|
end
|
|
31
|
-
|
|
31
|
+
|
|
32
32
|
it "should not overwrite the accessor when the element is not present" do
|
|
33
33
|
document = @klass.new
|
|
34
34
|
document.title = "Title"
|
|
@@ -47,7 +47,7 @@ describe "SAXMachine" do
|
|
|
47
47
|
document = @klass.parse("<title>My Title</title>")
|
|
48
48
|
document.title.should == "My Title"
|
|
49
49
|
end
|
|
50
|
-
|
|
50
|
+
|
|
51
51
|
it "should save cdata into an accessor" do
|
|
52
52
|
document = @klass.parse("<title><![CDATA[A Title]]></title>")
|
|
53
53
|
document.title.should == "A Title"
|
|
@@ -60,7 +60,7 @@ describe "SAXMachine" do
|
|
|
60
60
|
|
|
61
61
|
it "should save the first element text when there are multiple of the same element" do
|
|
62
62
|
document = @klass.parse("<xml><title>My Title</title><title>bar</title></xml>")
|
|
63
|
-
document.title.should == "My Title"
|
|
63
|
+
document.title.should == "My Title"
|
|
64
64
|
end
|
|
65
65
|
end
|
|
66
66
|
|
|
@@ -100,7 +100,7 @@ describe "SAXMachine" do
|
|
|
100
100
|
document.summary.should == "here is a description"
|
|
101
101
|
end
|
|
102
102
|
end
|
|
103
|
-
|
|
103
|
+
|
|
104
104
|
describe "using the :with option" do
|
|
105
105
|
describe "and the :value option" do
|
|
106
106
|
before :each do
|
|
@@ -109,17 +109,17 @@ describe "SAXMachine" do
|
|
|
109
109
|
element :link, :value => :href, :with => {:foo => "bar"}
|
|
110
110
|
end
|
|
111
111
|
end
|
|
112
|
-
|
|
112
|
+
|
|
113
113
|
it "should save the value of a matching element" do
|
|
114
114
|
document = @klass.parse("<link href='test' foo='bar'>asdf</link>")
|
|
115
115
|
document.link.should == "test"
|
|
116
116
|
end
|
|
117
|
-
|
|
117
|
+
|
|
118
118
|
it "should save the value of the first matching element" do
|
|
119
119
|
document = @klass.parse("<xml><link href='first' foo='bar' /><link href='second' foo='bar' /></xml>")
|
|
120
120
|
document.link.should == "first"
|
|
121
121
|
end
|
|
122
|
-
|
|
122
|
+
|
|
123
123
|
describe "and the :as option" do
|
|
124
124
|
before :each do
|
|
125
125
|
@klass = Class.new do
|
|
@@ -128,15 +128,15 @@ describe "SAXMachine" do
|
|
|
128
128
|
element :link, :value => :href, :as => :second_url, :with => {:asdf => "jkl"}
|
|
129
129
|
end
|
|
130
130
|
end
|
|
131
|
-
|
|
131
|
+
|
|
132
132
|
it "should save the value of the first matching element" do
|
|
133
133
|
document = @klass.parse("<xml><link href='first' foo='bar' /><link href='second' asdf='jkl' /><link href='second' foo='bar' /></xml>")
|
|
134
134
|
document.url.should == "first"
|
|
135
135
|
document.second_url.should == "second"
|
|
136
|
-
end
|
|
136
|
+
end
|
|
137
137
|
end
|
|
138
138
|
end
|
|
139
|
-
|
|
139
|
+
|
|
140
140
|
describe "with only one element" do
|
|
141
141
|
before :each do
|
|
142
142
|
@klass = Class.new do
|
|
@@ -157,15 +157,15 @@ describe "SAXMachine" do
|
|
|
157
157
|
|
|
158
158
|
it "should save the text of an element that has matching attributes when it is the second of that type" do
|
|
159
159
|
document = @klass.parse("<xml><link>no match</link><link foo=\"bar\">match</link></xml>")
|
|
160
|
-
document.link.should == "match"
|
|
160
|
+
document.link.should == "match"
|
|
161
161
|
end
|
|
162
|
-
|
|
162
|
+
|
|
163
163
|
it "should save the text of an element that has matching attributes plus a few more" do
|
|
164
164
|
document = @klass.parse("<xml><link>no match</link><link asdf='jkl' foo='bar'>match</link>")
|
|
165
165
|
document.link.should == "match"
|
|
166
166
|
end
|
|
167
167
|
end
|
|
168
|
-
|
|
168
|
+
|
|
169
169
|
describe "with multiple elements of same tag" do
|
|
170
170
|
before :each do
|
|
171
171
|
@klass = Class.new do
|
|
@@ -174,19 +174,19 @@ describe "SAXMachine" do
|
|
|
174
174
|
element :link, :as => :second, :with => {:asdf => "jkl"}
|
|
175
175
|
end
|
|
176
176
|
end
|
|
177
|
-
|
|
177
|
+
|
|
178
178
|
it "should match the first element" do
|
|
179
179
|
document = @klass.parse("<xml><link>no match</link><link foo=\"bar\">first match</link><link>no match</link></xml>")
|
|
180
180
|
document.first.should == "first match"
|
|
181
181
|
end
|
|
182
|
-
|
|
182
|
+
|
|
183
183
|
it "should match the second element" do
|
|
184
184
|
document = @klass.parse("<xml><link>no match</link><link foo='bar'>first match</link><link asdf='jkl'>second match</link><link>hi</link></xml>")
|
|
185
185
|
document.second.should == "second match"
|
|
186
186
|
end
|
|
187
187
|
end
|
|
188
188
|
end # using the 'with' option
|
|
189
|
-
|
|
189
|
+
|
|
190
190
|
describe "using the 'value' option" do
|
|
191
191
|
before :each do
|
|
192
192
|
@klass = Class.new do
|
|
@@ -194,22 +194,22 @@ describe "SAXMachine" do
|
|
|
194
194
|
element :link, :value => :foo
|
|
195
195
|
end
|
|
196
196
|
end
|
|
197
|
-
|
|
197
|
+
|
|
198
198
|
it "should save the attribute value" do
|
|
199
199
|
document = @klass.parse("<link foo='test'>hello</link>")
|
|
200
200
|
document.link.should == 'test'
|
|
201
201
|
end
|
|
202
|
-
|
|
202
|
+
|
|
203
203
|
it "should save the attribute value when there is no text enclosed by the tag" do
|
|
204
204
|
document = @klass.parse("<link foo='test'></link>")
|
|
205
205
|
document.link.should == 'test'
|
|
206
206
|
end
|
|
207
|
-
|
|
207
|
+
|
|
208
208
|
it "should save the attribute value when the tag close is in the open" do
|
|
209
209
|
document = @klass.parse("<link foo='test'/>")
|
|
210
210
|
document.link.should == 'test'
|
|
211
211
|
end
|
|
212
|
-
|
|
212
|
+
|
|
213
213
|
it "should save two different attribute values on a single tag" do
|
|
214
214
|
@klass = Class.new do
|
|
215
215
|
include SAXMachine
|
|
@@ -220,7 +220,7 @@ describe "SAXMachine" do
|
|
|
220
220
|
document.first.should == "foo value"
|
|
221
221
|
document.second.should == "bar value"
|
|
222
222
|
end
|
|
223
|
-
|
|
223
|
+
|
|
224
224
|
it "should not fail if one of the attribute hasn't been defined" do
|
|
225
225
|
@klass = Class.new do
|
|
226
226
|
include SAXMachine
|
|
@@ -232,7 +232,7 @@ describe "SAXMachine" do
|
|
|
232
232
|
document.second.should be_nil
|
|
233
233
|
end
|
|
234
234
|
end
|
|
235
|
-
|
|
235
|
+
|
|
236
236
|
describe "when desiring both the content and attributes of an element" do
|
|
237
237
|
before :each do
|
|
238
238
|
@klass = Class.new do
|
|
@@ -250,10 +250,47 @@ describe "SAXMachine" do
|
|
|
250
250
|
document.link_bar.should == 'test2'
|
|
251
251
|
end
|
|
252
252
|
end
|
|
253
|
-
|
|
253
|
+
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
describe "when using the class option" do
|
|
257
|
+
before :each do
|
|
258
|
+
class Foo
|
|
259
|
+
include SAXMachine
|
|
260
|
+
element :title
|
|
261
|
+
end
|
|
262
|
+
@klass = Class.new do
|
|
263
|
+
include SAXMachine
|
|
264
|
+
element :entry, :class => Foo
|
|
265
|
+
end
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
it "should parse a single element with children" do
|
|
269
|
+
document = @klass.parse("<entry><title>a title</title></entry>")
|
|
270
|
+
document.entry.title.should == "a title"
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
it "should use the first element when there are multiple of the same element" do
|
|
274
|
+
document = @klass.parse("<xml><entry><title>title 1</title></entry><entry><title>title 2</title></entry></xml>")
|
|
275
|
+
document.entry.title.should == "title 1"
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
it "should not parse a top level element that is specified only in a child" do
|
|
279
|
+
document = @klass.parse("<xml><title>no parse</title><entry><title>correct title</title></entry></xml>")
|
|
280
|
+
document.entry.title.should == "correct title"
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
it "should parse out an attribute value from the tag that starts the element" do
|
|
284
|
+
class Foo
|
|
285
|
+
element :entry, :value => :href, :as => :url
|
|
286
|
+
end
|
|
287
|
+
document = @klass.parse("<xml><entry href='http://pauldix.net'><title>paul</title></entry></xml>")
|
|
288
|
+
document.entry.title.should == "paul"
|
|
289
|
+
document.entry.url.should == "http://pauldix.net"
|
|
290
|
+
end
|
|
254
291
|
end
|
|
255
292
|
end
|
|
256
|
-
|
|
293
|
+
|
|
257
294
|
describe "elements" do
|
|
258
295
|
describe "when parsing multiple elements" do
|
|
259
296
|
before :each do
|
|
@@ -262,23 +299,23 @@ describe "SAXMachine" do
|
|
|
262
299
|
elements :entry, :as => :entries
|
|
263
300
|
end
|
|
264
301
|
end
|
|
265
|
-
|
|
302
|
+
|
|
266
303
|
it "should provide a collection accessor" do
|
|
267
304
|
document = @klass.new
|
|
268
305
|
document.entries << :foo
|
|
269
306
|
document.entries.should == [:foo]
|
|
270
307
|
end
|
|
271
|
-
|
|
308
|
+
|
|
272
309
|
it "should parse a single element" do
|
|
273
310
|
document = @klass.parse("<entry>hello</entry>")
|
|
274
311
|
document.entries.should == ["hello"]
|
|
275
312
|
end
|
|
276
|
-
|
|
313
|
+
|
|
277
314
|
it "should parse multiple elements" do
|
|
278
315
|
document = @klass.parse("<xml><entry>hello</entry><entry>world</entry></xml>")
|
|
279
316
|
document.entries.should == ["hello", "world"]
|
|
280
317
|
end
|
|
281
|
-
|
|
318
|
+
|
|
282
319
|
it "should parse multiple elements when taking an attribute value" do
|
|
283
320
|
attribute_klass = Class.new do
|
|
284
321
|
include SAXMachine
|
|
@@ -288,9 +325,10 @@ describe "SAXMachine" do
|
|
|
288
325
|
doc.entries.should == ["asdf", "jkl"]
|
|
289
326
|
end
|
|
290
327
|
end
|
|
291
|
-
|
|
328
|
+
|
|
292
329
|
describe "when using the class option" do
|
|
293
330
|
before :each do
|
|
331
|
+
Object.send(:remove_const, :Foo)
|
|
294
332
|
class Foo
|
|
295
333
|
include SAXMachine
|
|
296
334
|
element :title
|
|
@@ -300,26 +338,26 @@ describe "SAXMachine" do
|
|
|
300
338
|
elements :entry, :as => :entries, :class => Foo
|
|
301
339
|
end
|
|
302
340
|
end
|
|
303
|
-
|
|
341
|
+
|
|
304
342
|
it "should parse a single element with children" do
|
|
305
343
|
document = @klass.parse("<entry><title>a title</title></entry>")
|
|
306
344
|
document.entries.size.should == 1
|
|
307
345
|
document.entries.first.title.should == "a title"
|
|
308
346
|
end
|
|
309
|
-
|
|
347
|
+
|
|
310
348
|
it "should parse multiple elements with children" do
|
|
311
349
|
document = @klass.parse("<xml><entry><title>title 1</title></entry><entry><title>title 2</title></entry></xml>")
|
|
312
350
|
document.entries.size.should == 2
|
|
313
351
|
document.entries.first.title.should == "title 1"
|
|
314
352
|
document.entries.last.title.should == "title 2"
|
|
315
353
|
end
|
|
316
|
-
|
|
354
|
+
|
|
317
355
|
it "should not parse a top level element that is specified only in a child" do
|
|
318
356
|
document = @klass.parse("<xml><title>no parse</title><entry><title>correct title</title></entry></xml>")
|
|
319
357
|
document.entries.size.should == 1
|
|
320
358
|
document.entries.first.title.should == "correct title"
|
|
321
359
|
end
|
|
322
|
-
|
|
360
|
+
|
|
323
361
|
it "should parse out an attribute value from the tag that starts the collection" do
|
|
324
362
|
class Foo
|
|
325
363
|
element :entry, :value => :href, :as => :url
|
|
@@ -329,9 +367,9 @@ describe "SAXMachine" do
|
|
|
329
367
|
document.entries.first.title.should == "paul"
|
|
330
368
|
document.entries.first.url.should == "http://pauldix.net"
|
|
331
369
|
end
|
|
332
|
-
end
|
|
370
|
+
end
|
|
333
371
|
end
|
|
334
|
-
|
|
372
|
+
|
|
335
373
|
describe "full example" do
|
|
336
374
|
before :each do
|
|
337
375
|
@xml = File.read('spec/sax-machine/atom.xml')
|
|
@@ -344,7 +382,7 @@ describe "SAXMachine" do
|
|
|
344
382
|
element :content
|
|
345
383
|
element :published
|
|
346
384
|
end
|
|
347
|
-
|
|
385
|
+
|
|
348
386
|
class Atom
|
|
349
387
|
include SAXMachine
|
|
350
388
|
element :title
|
|
@@ -353,7 +391,7 @@ describe "SAXMachine" do
|
|
|
353
391
|
elements :entry, :as => :entries, :class => AtomEntry
|
|
354
392
|
end
|
|
355
393
|
end # before
|
|
356
|
-
|
|
394
|
+
|
|
357
395
|
it "should parse the url" do
|
|
358
396
|
f = Atom.parse(@xml)
|
|
359
397
|
f.url.should == "http://www.pauldix.net/"
|