sax-machine 0.0.20 → 0.1.0
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/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: []
|