sax-machine 0.0.20 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.textile +24 -3
- data/lib/sax-machine.rb +1 -0
- data/lib/sax-machine/{sax_parent_config.rb → sax_ancestor_config.rb} +1 -1
- data/lib/sax-machine/sax_config.rb +6 -6
- data/lib/sax-machine/sax_configure.rb +38 -0
- data/lib/sax-machine/sax_document.rb +2 -2
- data/lib/sax-machine/sax_handler.rb +3 -3
- data/spec/sax-machine/configure_sax_machine_spec.rb +53 -0
- data/spec/sax-machine/include_sax_machine_spec.rb +42 -0
- data/spec/sax-machine/sax_document_spec.rb +2 -2
- metadata +8 -5
data/README.textile
CHANGED
@@ -13,6 +13,15 @@ h2. Usage
|
|
13
13
|
<pre>
|
14
14
|
require 'sax-machine'
|
15
15
|
|
16
|
+
# Class for information associated with content parts in a feed.
|
17
|
+
# Ex: <content type="text">sample</content>
|
18
|
+
# instance.type will be "text", instance.text will be "sample"
|
19
|
+
class AtomContent
|
20
|
+
include SAXMachine
|
21
|
+
attribute :type
|
22
|
+
value :text
|
23
|
+
end
|
24
|
+
|
16
25
|
# Class for parsing an atom entry out of a feedburner atom feed
|
17
26
|
class AtomEntry
|
18
27
|
include SAXMachine
|
@@ -21,9 +30,9 @@ class AtomEntry
|
|
21
30
|
element :name, :as => :author
|
22
31
|
element "feedburner:origLink", :as => :url
|
23
32
|
element :summary
|
24
|
-
element :content
|
33
|
+
element :content, :class => AtomContent
|
25
34
|
element :published
|
26
|
-
|
35
|
+
ancestor :ancestor
|
27
36
|
end
|
28
37
|
|
29
38
|
# Class for parsing Atom feeds
|
@@ -48,11 +57,12 @@ feed.feed_url # => goes to the feedburner feed
|
|
48
57
|
feed.entries.first.title # => title of the first entry
|
49
58
|
feed.entries.first.author # => the author of the first entry
|
50
59
|
feed.entries.first.url # => the permalink on the blog for this entry
|
51
|
-
feed.entries.first.
|
60
|
+
feed.entries.first.ancestor # => the Atom ancestor
|
52
61
|
# etc ...
|
53
62
|
|
54
63
|
# you can also use the elements method without specifying a class like so
|
55
64
|
class SomeServiceResponse
|
65
|
+
include SAXMachine
|
56
66
|
elements :message, :as => :messages
|
57
67
|
end
|
58
68
|
|
@@ -61,6 +71,17 @@ response.messages.first # => "hi"
|
|
61
71
|
response.messages.last # => "world"
|
62
72
|
</pre>
|
63
73
|
|
74
|
+
# To limit conflicts in the class used for mappping, you can use the alternate SAXMachine.configure syntax
|
75
|
+
|
76
|
+
class X < ActiveRecord::Base
|
77
|
+
|
78
|
+
# this way no element, elements or ancestor method will be added to X
|
79
|
+
SAXMachine.configure(X) do |c|
|
80
|
+
c.element :title
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
|
64
85
|
h2. LICENSE
|
65
86
|
|
66
87
|
(The MIT License)
|
data/lib/sax-machine.rb
CHANGED
@@ -3,6 +3,7 @@ require "rubygems"
|
|
3
3
|
$LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__))) unless $LOAD_PATH.include?(File.expand_path(File.dirname(__FILE__)))
|
4
4
|
|
5
5
|
require "sax-machine/sax_document"
|
6
|
+
require "sax-machine/sax_configure"
|
6
7
|
require "sax-machine/sax_handler"
|
7
8
|
require "sax-machine/sax_config"
|
8
9
|
|
@@ -2,12 +2,12 @@ require "sax-machine/sax_attribute_config"
|
|
2
2
|
require "sax-machine/sax_element_value_config"
|
3
3
|
require "sax-machine/sax_element_config"
|
4
4
|
require "sax-machine/sax_collection_config"
|
5
|
-
require "sax-machine/
|
5
|
+
require "sax-machine/sax_ancestor_config"
|
6
6
|
|
7
7
|
module SAXMachine
|
8
8
|
class SAXConfig
|
9
9
|
|
10
|
-
attr_accessor :top_level_elements, :top_level_attributes, :top_level_element_value, :collection_elements, :
|
10
|
+
attr_accessor :top_level_elements, :top_level_attributes, :top_level_element_value, :collection_elements, :ancestors
|
11
11
|
|
12
12
|
def initialize
|
13
13
|
# Default value is an empty array
|
@@ -15,7 +15,7 @@ module SAXMachine
|
|
15
15
|
@top_level_attributes = []
|
16
16
|
@top_level_element_value = []
|
17
17
|
@collection_elements = Hash.new { |hash, key| hash[key] = [] }
|
18
|
-
@
|
18
|
+
@ancestors = []
|
19
19
|
end
|
20
20
|
|
21
21
|
def columns
|
@@ -28,7 +28,7 @@ module SAXMachine
|
|
28
28
|
@top_level_attributes = sax_config.top_level_attributes.clone
|
29
29
|
@top_level_element_value = sax_config.top_level_element_value.clone
|
30
30
|
@collection_elements = sax_config.collection_elements.clone
|
31
|
-
@
|
31
|
+
@ancestors = sax_config.ancestors.clone
|
32
32
|
end
|
33
33
|
|
34
34
|
def add_top_level_element(name, options)
|
@@ -47,8 +47,8 @@ module SAXMachine
|
|
47
47
|
@collection_elements[name.to_s] << CollectionConfig.new(name, options)
|
48
48
|
end
|
49
49
|
|
50
|
-
def
|
51
|
-
@
|
50
|
+
def add_ancestor(name, options)
|
51
|
+
@ancestors << AncestorConfig.new(name, options)
|
52
52
|
end
|
53
53
|
|
54
54
|
def collection_config(name, attrs)
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module SAXMachine
|
2
|
+
|
3
|
+
def self.configure(clazz)
|
4
|
+
extended_clazz = Class.new(clazz)
|
5
|
+
extended_clazz.send(:include, SAXMachine)
|
6
|
+
|
7
|
+
# override create_attr to create attributes on the original class
|
8
|
+
def extended_clazz.create_attr real_name
|
9
|
+
superclass.send(:attr_reader, real_name) unless superclass.method_defined?(real_name)
|
10
|
+
superclass.send(:attr_writer, real_name) unless superclass.method_defined?("#{real_name}=")
|
11
|
+
end
|
12
|
+
|
13
|
+
yield(extended_clazz)
|
14
|
+
|
15
|
+
clazz.extend LightWeightSaxMachine
|
16
|
+
clazz.sax_config = extended_clazz.sax_config
|
17
|
+
|
18
|
+
(class << clazz;self;end).send(:define_method, :parse) do |xml_text|
|
19
|
+
extended_clazz.parse(xml_text)
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
module LightWeightSaxMachine
|
25
|
+
|
26
|
+
attr_writer :sax_config
|
27
|
+
|
28
|
+
def sax_config
|
29
|
+
@sax_config ||= SAXConfig.new
|
30
|
+
end
|
31
|
+
|
32
|
+
def inherited(subclass)
|
33
|
+
subclass.sax_config.send(:initialize_copy, self.sax_config)
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
@@ -41,9 +41,9 @@ module SAXMachine
|
|
41
41
|
create_attr real_name
|
42
42
|
end
|
43
43
|
|
44
|
-
def
|
44
|
+
def ancestor(name, options = {})
|
45
45
|
real_name = (options[:as] ||= name).to_s
|
46
|
-
sax_config.
|
46
|
+
sax_config.add_ancestor(name, options)
|
47
47
|
create_attr(real_name)
|
48
48
|
end
|
49
49
|
|
@@ -72,11 +72,11 @@ module SAXMachine
|
|
72
72
|
mark_as_parsed(object, config)
|
73
73
|
end
|
74
74
|
|
75
|
-
# try to set the
|
75
|
+
# try to set the ancestor
|
76
76
|
sax_config = element.class.respond_to?(:sax_config) ? element.class.sax_config : nil
|
77
77
|
if sax_config
|
78
|
-
sax_config.
|
79
|
-
element.send(
|
78
|
+
sax_config.ancestors.each do |ancestor|
|
79
|
+
element.send(ancestor.setter, object)
|
80
80
|
end
|
81
81
|
end
|
82
82
|
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class A
|
4
|
+
|
5
|
+
SAXMachine.configure(A) do |c|
|
6
|
+
c.element :title
|
7
|
+
end
|
8
|
+
|
9
|
+
end
|
10
|
+
|
11
|
+
class B < A
|
12
|
+
|
13
|
+
SAXMachine.configure(B) do |c|
|
14
|
+
c.element :b
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
class C < B
|
20
|
+
|
21
|
+
SAXMachine.configure(C) do |c|
|
22
|
+
c.element :c
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "SAXMachine configure" do
|
28
|
+
before do
|
29
|
+
xml = "<top><title>Test</title><b>Matched!</b><c>And Again</c></top>"
|
30
|
+
@a = A.new
|
31
|
+
@a.parse xml
|
32
|
+
@b = B.new
|
33
|
+
@b.parse xml
|
34
|
+
@c = C.new
|
35
|
+
@c.parse xml
|
36
|
+
end
|
37
|
+
it { @a.should be_a(A) }
|
38
|
+
it { @a.should_not be_a(B) }
|
39
|
+
it { @a.should be_a(SAXMachine) }
|
40
|
+
it { @a.title.should == "Test" }
|
41
|
+
it { @b.should be_a(A) }
|
42
|
+
it { @b.should be_a(B) }
|
43
|
+
it { @b.should be_a(SAXMachine) }
|
44
|
+
it { @b.title.should == "Test" }
|
45
|
+
it { @b.b.should == "Matched!" }
|
46
|
+
it { @c.should be_a(A) }
|
47
|
+
it { @c.should be_a(B) }
|
48
|
+
it { @c.should be_a(C) }
|
49
|
+
it { @c.should be_a(SAXMachine) }
|
50
|
+
it { @c.title.should == "Test" }
|
51
|
+
it { @c.b.should == "Matched!" }
|
52
|
+
it { @c.c.should == "And Again" }
|
53
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class A
|
4
|
+
include SAXMachine
|
5
|
+
element :title
|
6
|
+
end
|
7
|
+
|
8
|
+
class B < A
|
9
|
+
element :b
|
10
|
+
end
|
11
|
+
|
12
|
+
class C < B
|
13
|
+
element :c
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "SAXMachine inheritance" do
|
17
|
+
before do
|
18
|
+
xml = "<top><title>Test</title><b>Matched!</b><c>And Again</c></top>"
|
19
|
+
@a = A.new
|
20
|
+
@a.parse xml
|
21
|
+
@b = B.new
|
22
|
+
@b.parse xml
|
23
|
+
@c = C.new
|
24
|
+
@c.parse xml
|
25
|
+
end
|
26
|
+
it { @a.should be_a(A) }
|
27
|
+
it { @a.should_not be_a(B) }
|
28
|
+
it { @a.should be_a(SAXMachine) }
|
29
|
+
it { @a.title.should == "Test" }
|
30
|
+
it { @b.should be_a(A) }
|
31
|
+
it { @b.should be_a(B) }
|
32
|
+
it { @b.should be_a(SAXMachine) }
|
33
|
+
it { @b.title.should == "Test" }
|
34
|
+
it { @b.b.should == "Matched!" }
|
35
|
+
it { @c.should be_a(A) }
|
36
|
+
it { @c.should be_a(B) }
|
37
|
+
it { @c.should be_a(C) }
|
38
|
+
it { @c.should be_a(SAXMachine) }
|
39
|
+
it { @c.title.should == "Test" }
|
40
|
+
it { @c.b.should == "Matched!" }
|
41
|
+
it { @c.c.should == "And Again" }
|
42
|
+
end
|
@@ -506,7 +506,7 @@ describe "SAXMachine" do
|
|
506
506
|
element :category, :value => :id, :as => :id
|
507
507
|
element :title
|
508
508
|
element :categories, :as => :collection, :class => CategoryCollection
|
509
|
-
|
509
|
+
ancestor :ancestor
|
510
510
|
end
|
511
511
|
class CategoryCollection
|
512
512
|
include SAXMachine
|
@@ -518,7 +518,7 @@ describe "SAXMachine" do
|
|
518
518
|
it "should parse the first category" do
|
519
519
|
@collection.categories.first.id.should == "1"
|
520
520
|
@collection.categories.first.title.should == "First"
|
521
|
-
@collection.categories.first.
|
521
|
+
@collection.categories.first.ancestor.should == @collection
|
522
522
|
end
|
523
523
|
|
524
524
|
it "should parse the nested category" do
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sax-machine
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 27
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
+
- 1
|
8
9
|
- 0
|
9
|
-
|
10
|
-
version: 0.0.20
|
10
|
+
version: 0.1.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Paul Dix
|
@@ -16,7 +16,7 @@ autorequire:
|
|
16
16
|
bindir: bin
|
17
17
|
cert_chain: []
|
18
18
|
|
19
|
-
date: 2011-
|
19
|
+
date: 2011-09-30 00:00:00 Z
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
22
22
|
name: nokogiri
|
@@ -44,18 +44,21 @@ extra_rdoc_files: []
|
|
44
44
|
|
45
45
|
files:
|
46
46
|
- lib/sax-machine.rb
|
47
|
+
- lib/sax-machine/sax_ancestor_config.rb
|
47
48
|
- lib/sax-machine/sax_attribute_config.rb
|
48
49
|
- lib/sax-machine/sax_config.rb
|
50
|
+
- lib/sax-machine/sax_configure.rb
|
49
51
|
- lib/sax-machine/sax_document.rb
|
50
52
|
- lib/sax-machine/sax_collection_config.rb
|
51
53
|
- lib/sax-machine/sax_element_config.rb
|
52
54
|
- lib/sax-machine/sax_element_value_config.rb
|
53
55
|
- lib/sax-machine/sax_handler.rb
|
54
|
-
- lib/sax-machine/sax_parent_config.rb
|
55
56
|
- README.textile
|
56
57
|
- Rakefile
|
57
58
|
- Gemfile
|
58
59
|
- spec/spec_helper.rb
|
60
|
+
- spec/sax-machine/configure_sax_machine_spec.rb
|
61
|
+
- spec/sax-machine/include_sax_machine_spec.rb
|
59
62
|
- spec/sax-machine/sax_document_spec.rb
|
60
63
|
homepage: http://github.com/pauldix/sax-machine
|
61
64
|
licenses: []
|