julien51-sax-machine 0.0.16 → 0.0.22
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.
- data/lib/sax-machine/sax_collection_config.rb +26 -3
- data/lib/sax-machine/sax_config.rb +18 -10
- data/lib/sax-machine/sax_document.rb +8 -3
- data/lib/sax-machine/sax_event_recorder.rb +35 -0
- data/lib/sax-machine/sax_handler.rb +10 -8
- data/lib/sax-machine.rb +3 -2
- data/spec/sax-machine/sax_document_spec.rb +221 -3
- metadata +9 -4
|
@@ -3,21 +3,44 @@ module SAXMachine
|
|
|
3
3
|
|
|
4
4
|
class CollectionConfig
|
|
5
5
|
attr_reader :name
|
|
6
|
+
attr_reader :default_xmlns
|
|
6
7
|
|
|
7
8
|
def initialize(name, options)
|
|
8
9
|
@name = name.to_s
|
|
9
10
|
@class = options[:class]
|
|
10
11
|
@as = options[:as].to_s
|
|
12
|
+
@xmlns = case options[:xmlns]
|
|
13
|
+
when Array then options[:xmlns]
|
|
14
|
+
when String then [options[:xmlns]]
|
|
15
|
+
else nil
|
|
16
|
+
end
|
|
17
|
+
@default_xmlns = options[:default_xmlns]
|
|
18
|
+
if @default_xmlns && @xmlns && !@xmlns.include?('')
|
|
19
|
+
@xmlns << ''
|
|
20
|
+
end
|
|
21
|
+
@record_events = options[:events]
|
|
11
22
|
end
|
|
12
23
|
|
|
13
|
-
def handler
|
|
14
|
-
|
|
24
|
+
def handler(nsstack)
|
|
25
|
+
if @default_xmlns && (nsstack.nil? || nsstack[''] == '')
|
|
26
|
+
nsstack = NSStack.new(nsstack, nsstack)
|
|
27
|
+
nsstack[''] = @default_xmlns
|
|
28
|
+
end
|
|
29
|
+
unless @record_events
|
|
30
|
+
SAXHandler.new(@class.new, nsstack)
|
|
31
|
+
else
|
|
32
|
+
SAXEventRecorder.new(nsstack)
|
|
33
|
+
end
|
|
15
34
|
end
|
|
16
35
|
|
|
17
36
|
def accessor
|
|
18
37
|
as
|
|
19
38
|
end
|
|
20
39
|
|
|
40
|
+
def xmlns_match?(ns)
|
|
41
|
+
@xmlns.nil? || @xmlns.include?(ns)
|
|
42
|
+
end
|
|
43
|
+
|
|
21
44
|
protected
|
|
22
45
|
|
|
23
46
|
def as
|
|
@@ -30,4 +53,4 @@ module SAXMachine
|
|
|
30
53
|
end
|
|
31
54
|
|
|
32
55
|
end
|
|
33
|
-
end
|
|
56
|
+
end
|
|
@@ -6,25 +6,34 @@ module SAXMachine
|
|
|
6
6
|
attr_reader :top_level_elements, :collection_elements
|
|
7
7
|
|
|
8
8
|
def initialize
|
|
9
|
-
@top_level_elements =
|
|
10
|
-
@collection_elements =
|
|
9
|
+
@top_level_elements = {}
|
|
10
|
+
@collection_elements = {}
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
def add_top_level_element(name, options)
|
|
14
|
-
@top_level_elements
|
|
14
|
+
@top_level_elements[name.to_s] ||= []
|
|
15
|
+
@top_level_elements[name.to_s] << ElementConfig.new(name, options)
|
|
15
16
|
end
|
|
16
17
|
|
|
17
18
|
def add_collection_element(name, options)
|
|
18
|
-
@collection_elements
|
|
19
|
+
@collection_elements[name.to_s] ||= []
|
|
20
|
+
@collection_elements[name.to_s] << CollectionConfig.new(name, options)
|
|
19
21
|
end
|
|
20
22
|
|
|
21
|
-
def collection_config(name)
|
|
22
|
-
|
|
23
|
+
def collection_config(name, nsstack)
|
|
24
|
+
prefix, name = name.split(':', 2)
|
|
25
|
+
prefix, name = nil, prefix unless name # No prefix
|
|
26
|
+
namespace = nsstack[prefix]
|
|
27
|
+
|
|
28
|
+
(@collection_elements[name.to_s] || []).detect { |ce|
|
|
29
|
+
ce.name.to_s == name.to_s &&
|
|
30
|
+
ce.xmlns_match?(namespace)
|
|
31
|
+
}
|
|
23
32
|
end
|
|
24
33
|
|
|
25
34
|
def element_configs_for_attribute(name, attrs)
|
|
26
|
-
|
|
27
|
-
|
|
35
|
+
name = name.split(':', 2).last
|
|
36
|
+
(@top_level_elements[name.to_s] || []).select do |element_config|
|
|
28
37
|
element_config.has_value_and_attrs_match?(attrs)
|
|
29
38
|
end
|
|
30
39
|
end
|
|
@@ -34,8 +43,7 @@ module SAXMachine
|
|
|
34
43
|
prefix, name = nil, prefix unless name # No prefix
|
|
35
44
|
namespace = nsstack[prefix]
|
|
36
45
|
|
|
37
|
-
@top_level_elements.detect do |element_config|
|
|
38
|
-
element_config.name == name &&
|
|
46
|
+
(@top_level_elements[name.to_s] || []).detect do |element_config|
|
|
39
47
|
element_config.xmlns_match?(namespace) &&
|
|
40
48
|
element_config.attrs_match?(attrs)
|
|
41
49
|
end
|
|
@@ -10,6 +10,7 @@ module SAXMachine
|
|
|
10
10
|
unless @parser
|
|
11
11
|
sax_handler = SAXHandler.new(self)
|
|
12
12
|
@parser = Nokogiri::XML::SAX::PushParser.new(sax_handler)
|
|
13
|
+
@parser.options |= Nokogiri::XML::ParseOptions::RECOVER if @parser.respond_to?(:options)
|
|
13
14
|
end
|
|
14
15
|
@parser << xml_text
|
|
15
16
|
self
|
|
@@ -43,11 +44,15 @@ module SAXMachine
|
|
|
43
44
|
end
|
|
44
45
|
|
|
45
46
|
def columns
|
|
46
|
-
|
|
47
|
+
r = []
|
|
48
|
+
sax_config.top_level_elements.each do |name, ecs|
|
|
49
|
+
r += ecs
|
|
50
|
+
end
|
|
51
|
+
r
|
|
47
52
|
end
|
|
48
53
|
|
|
49
54
|
def column(sym)
|
|
50
|
-
|
|
55
|
+
(sax_config.top_level_elements[sym.to_s] || []).first
|
|
51
56
|
end
|
|
52
57
|
|
|
53
58
|
def data_class(sym)
|
|
@@ -64,7 +69,7 @@ module SAXMachine
|
|
|
64
69
|
|
|
65
70
|
def elements(name, options = {})
|
|
66
71
|
options[:as] ||= name
|
|
67
|
-
if options[:class]
|
|
72
|
+
if options[:class] || options[:events]
|
|
68
73
|
sax_config.add_collection_element(name, options)
|
|
69
74
|
else
|
|
70
75
|
class_eval <<-SRC
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
module SAXMachine
|
|
2
|
+
class SAXEventRecorder < SAXHandler
|
|
3
|
+
def initialize(nsstack)
|
|
4
|
+
super(nil, nsstack)
|
|
5
|
+
@events = []
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def object
|
|
9
|
+
# First and last belong to the parent element
|
|
10
|
+
@events[1..-2]
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def start_element(name, attrs = [])
|
|
14
|
+
@nsstack = NSStack.new(@nsstack, attrs)
|
|
15
|
+
prefix, name = name.split(':', 2)
|
|
16
|
+
prefix, name = nil, prefix unless name
|
|
17
|
+
@events << [:start_element, @nsstack[prefix], name, attrs]
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def end_element(name)
|
|
21
|
+
prefix, name = name.split(':', 2)
|
|
22
|
+
prefix, name = nil, prefix unless name
|
|
23
|
+
@events << [:end_element, @nsstack[prefix], name]
|
|
24
|
+
@nsstack = @nsstack.pop
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def characters(string)
|
|
28
|
+
@events << [:chars, string]
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def sax_config
|
|
32
|
+
raise
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -5,9 +5,9 @@ module SAXMachine
|
|
|
5
5
|
class SAXHandler < Nokogiri::XML::SAX::Document
|
|
6
6
|
attr_reader :object
|
|
7
7
|
|
|
8
|
-
def initialize(object)
|
|
8
|
+
def initialize(object, nsstack=nil)
|
|
9
9
|
@object = object
|
|
10
|
-
@nsstack =
|
|
10
|
+
@nsstack = nsstack || NSStack.new
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
def characters(string)
|
|
@@ -23,7 +23,7 @@ module SAXMachine
|
|
|
23
23
|
end
|
|
24
24
|
|
|
25
25
|
def start_element(name, attrs = [])
|
|
26
|
-
|
|
26
|
+
|
|
27
27
|
@name = name
|
|
28
28
|
@attrs = attrs.map { |a| SAXHandler.decode_xml(a) }
|
|
29
29
|
@nsstack = NSStack.new(@nsstack, @attrs)
|
|
@@ -31,10 +31,11 @@ module SAXMachine
|
|
|
31
31
|
if parsing_collection?
|
|
32
32
|
@collection_handler.start_element(@name, @attrs)
|
|
33
33
|
|
|
34
|
-
elsif @collection_config = sax_config.collection_config(@name)
|
|
35
|
-
@collection_handler = @collection_config.handler
|
|
36
|
-
@
|
|
37
|
-
|
|
34
|
+
elsif @collection_config = sax_config.collection_config(@name, @nsstack)
|
|
35
|
+
@collection_handler = @collection_config.handler(@nsstack)
|
|
36
|
+
if @object.class != @collection_handler.object.class
|
|
37
|
+
@collection_handler.start_element(@name, @attrs)
|
|
38
|
+
end
|
|
38
39
|
elsif (element_configs = sax_config.element_configs_for_attribute(@name, @attrs)).any?
|
|
39
40
|
parse_element_attributes(element_configs)
|
|
40
41
|
set_element_config_for_element_value
|
|
@@ -45,7 +46,8 @@ module SAXMachine
|
|
|
45
46
|
end
|
|
46
47
|
|
|
47
48
|
def end_element(name)
|
|
48
|
-
if parsing_collection? && @collection_config.name == name
|
|
49
|
+
if parsing_collection? && @collection_config.name == name.split(':').last
|
|
50
|
+
@collection_handler.end_element(name)
|
|
49
51
|
@object.send(@collection_config.accessor) << @collection_handler.object
|
|
50
52
|
reset_current_collection
|
|
51
53
|
|
data/lib/sax-machine.rb
CHANGED
|
@@ -326,6 +326,46 @@ describe "SAXMachine" do
|
|
|
326
326
|
document = @klass.parse("<x:b>hello</x:b>")
|
|
327
327
|
document.b.should == 'hello'
|
|
328
328
|
end
|
|
329
|
+
|
|
330
|
+
it "should get the namespaced element even it's not first" do
|
|
331
|
+
document = @klass.parse("<root xmlns:a='urn:test'><a>foo</a><a>foo</a><a:a>bar</a:a></root>")
|
|
332
|
+
document.a.should == 'bar'
|
|
333
|
+
end
|
|
334
|
+
|
|
335
|
+
it "should parse multiple namespaces" do
|
|
336
|
+
klass = Class.new do
|
|
337
|
+
include SAXMachine
|
|
338
|
+
element :a, :xmlns => 'urn:test'
|
|
339
|
+
element :b, :xmlns => 'urn:test2'
|
|
340
|
+
end
|
|
341
|
+
document = klass.parse("<root xmlns='urn:test' xmlns:b='urn:test2'><b:b>bar</b:b><a>foo</a></root>")
|
|
342
|
+
document.a.should == 'foo'
|
|
343
|
+
document.b.should == 'bar'
|
|
344
|
+
end
|
|
345
|
+
|
|
346
|
+
context "when passing a default namespace" do
|
|
347
|
+
before :all do
|
|
348
|
+
@xmlns = 'urn:test'
|
|
349
|
+
class Inner
|
|
350
|
+
include SAXMachine
|
|
351
|
+
element :a, :xmlns => @xmlns
|
|
352
|
+
end
|
|
353
|
+
@outer = Class.new do
|
|
354
|
+
include SAXMachine
|
|
355
|
+
elements :root, :default_xmlns => @xmlns, :class => Inner
|
|
356
|
+
end
|
|
357
|
+
end
|
|
358
|
+
|
|
359
|
+
it "should replace the empty namespace with a default" do
|
|
360
|
+
document = @outer.parse("<root><a>Hello</a></root>")
|
|
361
|
+
document.root[0].a.should == 'Hello'
|
|
362
|
+
end
|
|
363
|
+
|
|
364
|
+
it "should not replace another namespace" do
|
|
365
|
+
document = @outer.parse("<root xmlns='urn:test2'><a>Hello</a></root>")
|
|
366
|
+
document.root[0].a.should == 'Hello'
|
|
367
|
+
end
|
|
368
|
+
end
|
|
329
369
|
end
|
|
330
370
|
|
|
331
371
|
end
|
|
@@ -333,7 +373,7 @@ describe "SAXMachine" do
|
|
|
333
373
|
|
|
334
374
|
describe "elements" do
|
|
335
375
|
describe "when parsing multiple elements" do
|
|
336
|
-
before :
|
|
376
|
+
before :all do
|
|
337
377
|
@klass = Class.new do
|
|
338
378
|
include SAXMachine
|
|
339
379
|
elements :entry, :as => :entries
|
|
@@ -407,16 +447,63 @@ describe "SAXMachine" do
|
|
|
407
447
|
document.entries.first.url.should == "http://pauldix.net"
|
|
408
448
|
end
|
|
409
449
|
end
|
|
450
|
+
|
|
451
|
+
describe "when desiring sax events" do
|
|
452
|
+
XHTML_XMLNS = "http://www.w3.org/1999/xhtml"
|
|
453
|
+
|
|
454
|
+
before :all do
|
|
455
|
+
@klass = Class.new do
|
|
456
|
+
include SAXMachine
|
|
457
|
+
elements :body, :events => true
|
|
458
|
+
end
|
|
459
|
+
end
|
|
460
|
+
|
|
461
|
+
it "should parse a simple child" do
|
|
462
|
+
document = @klass.parse("<body><p/></body>")
|
|
463
|
+
document.body[0].should == [[:start_element, "", "p", []],
|
|
464
|
+
[:end_element, "", "p"]]
|
|
465
|
+
end
|
|
466
|
+
it "should parse a simple child with text" do
|
|
467
|
+
document = @klass.parse("<body><p>Hello</p></body>")
|
|
468
|
+
document.body[0].should == [[:start_element, "", "p", []],
|
|
469
|
+
[:chars, "Hello"],
|
|
470
|
+
[:end_element, "", "p"]]
|
|
471
|
+
end
|
|
472
|
+
it "should parse nested children" do
|
|
473
|
+
document = @klass.parse("<body><p><span/></p></body>")
|
|
474
|
+
document.body[0].should == [[:start_element, "", "p", []],
|
|
475
|
+
[:start_element, "", "span", []],
|
|
476
|
+
[:end_element, "", "span"],
|
|
477
|
+
[:end_element, "", "p"]]
|
|
478
|
+
end
|
|
479
|
+
it "should parse multiple children" do
|
|
480
|
+
document = @klass.parse("<body><p>Hello</p><p>World</p></body>")
|
|
481
|
+
document.body[0].should == [[:start_element, "", "p", []],
|
|
482
|
+
[:chars, "Hello"],
|
|
483
|
+
[:end_element, "", "p"],
|
|
484
|
+
[:start_element, "", "p", []],
|
|
485
|
+
[:chars, "World"],
|
|
486
|
+
[:end_element, "", "p"]]
|
|
487
|
+
end
|
|
488
|
+
it "should pass namespaces" do
|
|
489
|
+
document = @klass.parse("<body xmlns='#{XHTML_XMLNS}'><p/></body>")
|
|
490
|
+
document.body[0].should == [[:start_element, XHTML_XMLNS, "p", []],
|
|
491
|
+
[:end_element, XHTML_XMLNS, "p"]]
|
|
492
|
+
end
|
|
493
|
+
end
|
|
410
494
|
end
|
|
411
495
|
|
|
412
496
|
describe "full example" do
|
|
497
|
+
XMLNS_ATOM = "http://www.w3.org/2005/Atom"
|
|
498
|
+
XMLNS_FEEDBURNER = "http://rssnamespace.org/feedburner/ext/1.0"
|
|
499
|
+
|
|
413
500
|
before :each do
|
|
414
501
|
@xml = File.read('spec/sax-machine/atom.xml')
|
|
415
502
|
class AtomEntry
|
|
416
503
|
include SAXMachine
|
|
417
504
|
element :title
|
|
418
505
|
element :name, :as => :author
|
|
419
|
-
element
|
|
506
|
+
element :origLink, :as => :orig_link, :xmlns => XMLNS_FEEDBURNER
|
|
420
507
|
element :summary
|
|
421
508
|
element :content
|
|
422
509
|
element :published
|
|
@@ -427,7 +514,7 @@ describe "SAXMachine" do
|
|
|
427
514
|
element :title
|
|
428
515
|
element :link, :value => :href, :as => :url, :with => {:type => "text/html"}
|
|
429
516
|
element :link, :value => :href, :as => :feed_url, :with => {:type => "application/atom+xml"}
|
|
430
|
-
elements :entry, :as => :entries, :class => AtomEntry
|
|
517
|
+
elements :entry, :as => :entries, :class => AtomEntry, :xmlns => XMLNS_ATOM
|
|
431
518
|
end
|
|
432
519
|
end # before
|
|
433
520
|
|
|
@@ -435,5 +522,136 @@ describe "SAXMachine" do
|
|
|
435
522
|
f = Atom.parse(@xml)
|
|
436
523
|
f.url.should == "http://www.pauldix.net/"
|
|
437
524
|
end
|
|
525
|
+
|
|
526
|
+
it "should parse all entries" do
|
|
527
|
+
f = Atom.parse(@xml)
|
|
528
|
+
f.entries.length.should == 5
|
|
529
|
+
end
|
|
530
|
+
|
|
531
|
+
it "should parse the feedburner:origLink" do
|
|
532
|
+
f = Atom.parse(@xml)
|
|
533
|
+
f.entries[0].orig_link.should == 'http://www.pauldix.net/2008/09/marshal-data-to.html'
|
|
534
|
+
end
|
|
535
|
+
end
|
|
536
|
+
|
|
537
|
+
describe "another full example" do
|
|
538
|
+
|
|
539
|
+
RSS_XMLNS = 'http://purl.org/rss/1.0/'
|
|
540
|
+
ATOM_XMLNS = 'http://www.w3.org/2005/Atom'
|
|
541
|
+
class Entry
|
|
542
|
+
include SAXMachine
|
|
543
|
+
element :title, :xmlns => RSS_XMLNS
|
|
544
|
+
element :title, :xmlns => ATOM_XMLNS
|
|
545
|
+
element :link, :xmlns => RSS_XMLNS
|
|
546
|
+
element :link, :xmlns => ATOM_XMLNS, :value => 'href'
|
|
547
|
+
end
|
|
548
|
+
class Channel
|
|
549
|
+
include SAXMachine
|
|
550
|
+
element :title, :xmlns => RSS_XMLNS
|
|
551
|
+
element :title, :xmlns => ATOM_XMLNS
|
|
552
|
+
element :link, :xmlns => RSS_XMLNS
|
|
553
|
+
element :link, :xmlns => ATOM_XMLNS, :value => 'href'
|
|
554
|
+
elements :entry, :as => :entries, :class => Entry
|
|
555
|
+
elements :item, :as => :entries, :class => Entry
|
|
556
|
+
end
|
|
557
|
+
class Root
|
|
558
|
+
include SAXMachine
|
|
559
|
+
elements :rss, :as => :channels, :default_xmlns => RSS_XMLNS, :class => Channel
|
|
560
|
+
elements :feed, :as => :channels, :default_xmlns => ATOM_XMLNS, :class => Channel
|
|
561
|
+
end
|
|
562
|
+
|
|
563
|
+
context "when parsing a complex example" do
|
|
564
|
+
before :all do
|
|
565
|
+
@document = Root.parse(<<-eoxml).channels[0]
|
|
566
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
567
|
+
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"
|
|
568
|
+
xmlns:content="http://purl.org/rss/1.0/modules/content/"
|
|
569
|
+
xmlns:wfw="http://wellformedweb.org/CommentAPI/"
|
|
570
|
+
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
571
|
+
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
|
572
|
+
xmlns:cc="http://web.resource.org/cc/">
|
|
573
|
+
<channel>
|
|
574
|
+
<title>Delicious/tag/pubsubhubbub</title>
|
|
575
|
+
<atom:link rel="self" type="application/rss+xml" href="http://feeds.delicious.com/v2/rss/tag/pubsubhubbub?count=15"/>
|
|
576
|
+
<link>http://delicious.com/tag/pubsubhubbub</link>
|
|
577
|
+
<description>recent bookmarks tagged pubsubhubbub</description>
|
|
578
|
+
</channel>
|
|
579
|
+
</rss>
|
|
580
|
+
eoxml
|
|
581
|
+
end
|
|
582
|
+
it "should parse the title" do
|
|
583
|
+
@document.title.should == 'Delicious/tag/pubsubhubbub'
|
|
584
|
+
end
|
|
585
|
+
it "should parse the link" do
|
|
586
|
+
@document.link.should == 'http://feeds.delicious.com/v2/rss/tag/pubsubhubbub?count=15'
|
|
587
|
+
end
|
|
588
|
+
end
|
|
589
|
+
end
|
|
590
|
+
|
|
591
|
+
describe "yet another full example" do
|
|
592
|
+
|
|
593
|
+
context "when parsing a Twitter example" do
|
|
594
|
+
before :all do
|
|
595
|
+
|
|
596
|
+
RSS_XMLNS = ['http://purl.org/rss/1.0/', '']
|
|
597
|
+
|
|
598
|
+
ATOM_XMLNS = 'http://www.w3.org/2005/Atom' unless defined? ATOM_XMLNS
|
|
599
|
+
class Link
|
|
600
|
+
include SAXMachine
|
|
601
|
+
end
|
|
602
|
+
|
|
603
|
+
class Entry
|
|
604
|
+
include SAXMachine
|
|
605
|
+
element :title, :xmlns => RSS_XMLNS
|
|
606
|
+
element :link, :xmlns => RSS_XMLNS, :as => :entry_link
|
|
607
|
+
element :title, :xmlns => ATOM_XMLNS, :as => :title
|
|
608
|
+
elements :link, :xmlns => ATOM_XMLNS, :as => :links, :class => Link
|
|
609
|
+
end
|
|
610
|
+
|
|
611
|
+
class Feed
|
|
612
|
+
include SAXMachine
|
|
613
|
+
element :title, :xmlns => RSS_XMLNS, :as => :title
|
|
614
|
+
element :link, :xmlns => RSS_XMLNS, :as => :feed_link
|
|
615
|
+
elements :item, :xmlns => RSS_XMLNS, :as => :entries, :class => Entry
|
|
616
|
+
element :title, :xmlns => ATOM_XMLNS, :as => :title
|
|
617
|
+
elements :link, :xmlns => ATOM_XMLNS, :as => :links, :class => Link
|
|
618
|
+
end
|
|
619
|
+
|
|
620
|
+
@document = Feed.parse(<<-eoxml)
|
|
621
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
622
|
+
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
|
623
|
+
<channel>
|
|
624
|
+
<atom:link type="application/rss+xml" rel="self" href="http://twitter.com/statuses/user_timeline/5381582.rss"/>
|
|
625
|
+
<title>Twitter / julien51</title>
|
|
626
|
+
<link>http://twitter.com/julien51</link>
|
|
627
|
+
<description>Twitter updates from julien / julien51.</description>
|
|
628
|
+
<language>en-us</language>
|
|
629
|
+
<ttl>40</ttl>
|
|
630
|
+
<item>
|
|
631
|
+
<title>julien51: @github : I get an error when trying to build one of my gems (julien51-sax-machine), it seems related to another gem's gemspec.</title>
|
|
632
|
+
<description>julien51: @github : I get an error when trying to build one of my gems (julien51-sax-machine), it seems related to another gem's gemspec.</description>
|
|
633
|
+
<pubDate>Thu, 30 Jul 2009 01:00:30 +0000</pubDate>
|
|
634
|
+
<guid>http://twitter.com/julien51/statuses/2920716033</guid>
|
|
635
|
+
<link>http://twitter.com/julien51/statuses/2920716033</link>
|
|
636
|
+
</item>
|
|
637
|
+
<item>
|
|
638
|
+
<title>julien51: Hum, San Francisco's summer are delightful. http://bit.ly/VeXt4</title>
|
|
639
|
+
<description>julien51: Hum, San Francisco's summer are delightful. http://bit.ly/VeXt4</description>
|
|
640
|
+
<pubDate>Wed, 29 Jul 2009 23:07:32 +0000</pubDate>
|
|
641
|
+
<guid>http://twitter.com/julien51/statuses/2918869948</guid>
|
|
642
|
+
<link>http://twitter.com/julien51/statuses/2918869948</link>
|
|
643
|
+
</item>
|
|
644
|
+
</channel>
|
|
645
|
+
</rss>
|
|
646
|
+
eoxml
|
|
647
|
+
end
|
|
648
|
+
it "should parse the title" do
|
|
649
|
+
@document.title.should == 'Twitter / julien51'
|
|
650
|
+
end
|
|
651
|
+
|
|
652
|
+
it "should find an entry" do
|
|
653
|
+
@document.entries.length.should == 2
|
|
654
|
+
end
|
|
655
|
+
end
|
|
438
656
|
end
|
|
439
657
|
end
|
metadata
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: julien51-sax-machine
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
4
|
+
version: 0.0.22
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Paul Dix
|
|
8
|
+
- astro
|
|
9
|
+
- julien51
|
|
10
|
+
- superfeedr
|
|
8
11
|
autorequire:
|
|
9
12
|
bindir: bin
|
|
10
13
|
cert_chain: []
|
|
@@ -38,14 +41,16 @@ files:
|
|
|
38
41
|
- lib/sax-machine/sax_document.rb
|
|
39
42
|
- lib/sax-machine/sax_handler.rb
|
|
40
43
|
- lib/sax-machine/ns_stack.rb
|
|
44
|
+
- lib/sax-machine/sax_event_recorder.rb
|
|
41
45
|
- README.textile
|
|
42
46
|
- Rakefile
|
|
43
47
|
- spec/spec.opts
|
|
44
48
|
- spec/spec_helper.rb
|
|
45
49
|
- spec/sax-machine/sax_document_spec.rb
|
|
46
|
-
has_rdoc:
|
|
47
|
-
homepage: http://github.com/
|
|
48
|
-
licenses:
|
|
50
|
+
has_rdoc: true
|
|
51
|
+
homepage: http://github.com/julien51/sax-machine
|
|
52
|
+
licenses: []
|
|
53
|
+
|
|
49
54
|
post_install_message:
|
|
50
55
|
rdoc_options: []
|
|
51
56
|
|