UnderpantsGnome-sax-machine 0.0.13 → 0.0.14
Sign up to get free protection for your applications and to get access to all the features.
@@ -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/"
|