kind_dom 0.9.3 → 0.9.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,126 @@
1
+ require 'kind_dom/object_proxy'
2
+ require 'xml/libxml'
3
+
4
+ module KindDom
5
+
6
+ # KindDom provides graceful access to the the DOM of an XML document using
7
+ # three methods of Kindness:
8
+ # - <tt>#collection_of</tt> to select a collection of nodes
9
+ # - <tt>#first_of</tt> to select one node
10
+ # - <tt>#content_for</tt> to get node content.
11
+ #
12
+ # The original libxml behavior of the parsed document is preserved.
13
+ #
14
+ # As a contrived example, in the controller:
15
+ # @results = KindDom.new(xml_data)
16
+ #
17
+ # In the view:
18
+ #
19
+ # <% @results.first_of('//item') do |item| -%>
20
+ # <p>(This block is only executed if `item` is found.)</p>
21
+ #
22
+ # <% item.content_for('title') do |title| -%>
23
+ # <h2><%=h title %></h2>
24
+ # <p>(This block is only executed if `title` has content.)</p>
25
+ # <% end -%>
26
+ #
27
+ # <% item.content_for('description') do |description| -%>
28
+ # <p><%=h description %></p>
29
+ # <p>(This block is only executed if `description` has content.)</p>
30
+ # <% end -%>
31
+ # <% end -%>
32
+ #
33
+ class Base < ObjectProxy
34
+
35
+ attr_accessor :dom
36
+
37
+ def initialize(raw_xml=nil)
38
+ unless raw_xml.blank?
39
+ parser = XML::Parser.new
40
+ parser.string = raw_xml
41
+ @dom = parser.parse
42
+ end
43
+ rescue XML::Parser::ParseError
44
+ ensure
45
+ @dom.extend Kindness
46
+ super(@dom) # Proxy all method calls to @dom.
47
+ end
48
+
49
+ module Kindness
50
+ # Retrieve the contents of the first node or attribute selected by the XPath.
51
+ #
52
+ # Optional second argument is the default value to return if the DOM find fails.
53
+ #
54
+ # When a block is provided, it will be called with the found content
55
+ # (or default) before returning.
56
+ #
57
+ def content_for(xpath, default=nil) # :yields: found_content
58
+ node = case self.class.to_s
59
+ when 'XML::Document' then
60
+ root.find_first(xpath)
61
+ else # 'XML::Node'
62
+ find_first(xpath)
63
+ end
64
+ content = case node.class.to_s
65
+ when 'XML::Attr' then
66
+ node.value
67
+ else
68
+ node.content
69
+ end
70
+ rescue NoMethodError
71
+ ensure
72
+ content = content.blank? ? default : content
73
+ if block_given? and !content.blank?
74
+ return yield(content)
75
+ else
76
+ return content
77
+ end
78
+ end
79
+
80
+ # Retrieve a collection (Array) of DOM nodes selected by the XPath.
81
+ #
82
+ # Each node is extended with Kindness to support #content_for, #collection_of & #first_of.
83
+ #
84
+ # When a block is provided, it will be called with the found collection
85
+ # (or default) before returning.
86
+ #
87
+ def collection_of(xpath, default=nil) # :yields: found_collection
88
+ c = find(xpath).collect {|n| n.extend Kindness }
89
+ rescue NoMethodError
90
+ ensure
91
+ c = c.blank?||c.size<1 ? default : c
92
+ if block_given? and !c.nil?
93
+ return yield(c)
94
+ else
95
+ return c
96
+ end
97
+ end
98
+
99
+ # Retrieve the first DOM node selected by the XPath.
100
+ #
101
+ # The node is extended with Kindness to support #content_for, #collection_of & #first_of.
102
+ #
103
+ # When a block is provided, it will be called with the found node
104
+ # (or default) before returning.
105
+ #
106
+ def first_of(xpath, default=nil) # :yields: found_node
107
+ n = case self.class.to_s
108
+ when 'XML::Document' then
109
+ root.find_first(xpath)
110
+ else # 'XML::Node'
111
+ find_first(xpath)
112
+ end
113
+ n.extend Kindness
114
+ rescue NoMethodError
115
+ ensure
116
+ n = n.blank? ? default : n
117
+ if block_given? and !n.blank?
118
+ return yield(n)
119
+ else
120
+ return n
121
+ end
122
+ end
123
+ end
124
+
125
+ end
126
+ end
@@ -0,0 +1,31 @@
1
+ module KindDom
2
+
3
+ # The foundation of an object proxy is the BlankSlate.
4
+ #
5
+ # BlankSlate is included with Rails ActiveSupport
6
+ # as active_support/vendor/builder-2.1.2/blankslate.rb
7
+ #
8
+ # From the Rails rdoc: "BlankSlate provides an abstract base class with
9
+ # no predefined methods (except for __send__ and __id__). BlankSlate is useful
10
+ # as a base class when writing classes that depend upon method_missing
11
+ # (e.g. dynamic proxies)."
12
+ #
13
+ # ObjectProxy is a bare-bones proxy. Override #method_missing in your subclass
14
+ # to handle method calls in the proxy.
15
+ #
16
+ class ObjectProxy < BlankSlate
17
+
18
+ # Create a proxy to the provided object.
19
+ def initialize(target)
20
+ @target = target
21
+ end
22
+
23
+ # Override #method_missing in your subclass
24
+ # to handle method calls in the proxy; call `super(sym, *args, &block)`
25
+ # therein to get a response from the proxied object.
26
+ def method_missing(sym, *args, &block)
27
+ @target.__send__(sym, *args, &block)
28
+ end
29
+ end
30
+
31
+ end
data/lib/kind_dom.rb CHANGED
@@ -1,125 +1,9 @@
1
- require 'object_proxy'
2
- require 'active_support'
3
- require 'xml/libxml'
1
+ $:.unshift(File.dirname(__FILE__)) unless
2
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
4
3
 
5
-
6
- # KindDom provides graceful access to the the DOM of an XML document using
7
- # three methods of Kindness:
8
- # - <tt>#collection_of</tt> to select a collection of nodes
9
- # - <tt>#first_of</tt> to select one node
10
- # - <tt>#content_for</tt> to get node content.
11
- #
12
- # The original libxml behavior of the parsed document is preserved.
13
- #
14
- # As a contrived example, in the controller:
15
- # @results = KindDom.new(xml_data)
16
- #
17
- # In the view:
18
- #
19
- # <% @results.first_of('//item') do |item| -%>
20
- # <p>(This block is only executed if `item` is found.)</p>
21
- #
22
- # <% item.content_for('title') do |title| -%>
23
- # <h2><%=h title %></h2>
24
- # <p>(This block is only executed if `title` has content.)</p>
25
- # <% end -%>
26
- #
27
- # <% item.content_for('description') do |description| -%>
28
- # <p><%=h description %></p>
29
- # <p>(This block is only executed if `description` has content.)</p>
30
- # <% end -%>
31
- # <% end -%>
32
- #
33
- class KindDom < ObjectProxy
34
-
35
- attr_accessor :dom
36
-
37
- def initialize(raw_xml=nil)
38
- unless raw_xml.nil?
39
- parser = XML::Parser.new
40
- parser.string = raw_xml
41
- @dom = parser.parse
42
- end
43
- rescue XML::Parser::ParseError
44
- ensure
45
- @dom.extend Kindness
46
- super(@dom) # Proxy all method calls to @dom.
47
- end
48
-
49
- module Kindness
50
- # Retrieve the contents of the first node or attribute selected by the XPath.
51
- #
52
- # Optional second argument is the default value to return if the DOM find fails.
53
- #
54
- # When a block is provided, it will be called with the found content
55
- # (or default) before returning.
56
- #
57
- def content_for(xpath, default=nil) # :yields: found_content
58
- node = case self.class.to_s
59
- when 'XML::Document' then
60
- root.find_first(xpath)
61
- else # 'XML::Node'
62
- find_first(xpath)
63
- end
64
- content = case node.class.to_s
65
- when 'XML::Attr' then
66
- node.value
67
- else
68
- node.content
69
- end
70
- rescue NoMethodError
71
- ensure
72
- content = content.blank? ? default : content
73
- if block_given? and !content.blank?
74
- return yield(content)
75
- else
76
- return content
77
- end
78
- end
79
-
80
- # Retrieve a collection (Array) of DOM nodes selected by the XPath.
81
- #
82
- # Each node is extended with Kindness to support #content_for, #collection_of & #first_of.
83
- #
84
- # When a block is provided, it will be called with the found collection
85
- # (or default) before returning.
86
- #
87
- def collection_of(xpath, default=nil) # :yields: found_collection
88
- c = find(xpath).collect {|n| n.extend Kindness }
89
- rescue NoMethodError
90
- ensure
91
- c = c.blank?||c.size<1 ? default : c
92
- if block_given? and !c.nil?
93
- return yield(c)
94
- else
95
- return c
96
- end
97
- end
98
-
99
- # Retrieve the first DOM node selected by the XPath.
100
- #
101
- # The node is extended with Kindness to support #content_for, #collection_of & #first_of.
102
- #
103
- # When a block is provided, it will be called with the found node
104
- # (or default) before returning.
105
- #
106
- def first_of(xpath, default=nil) # :yields: found_node
107
- n = case self.class.to_s
108
- when 'XML::Document' then
109
- root.find_first(xpath)
110
- else # 'XML::Node'
111
- find_first(xpath)
112
- end
113
- n.extend Kindness
114
- rescue NoMethodError
115
- ensure
116
- n = n.blank? ? default : n
117
- if block_given? and !n.blank?
118
- return yield(n)
119
- else
120
- return n
121
- end
122
- end
123
- end
124
-
4
+ unless defined? ActiveSupport
5
+ require 'rubygems'
6
+ require 'active_support'
125
7
  end
8
+
9
+ require 'kind_dom/base'
@@ -3,7 +3,7 @@ require File.dirname(__FILE__) + '/../lib/kind_dom'
3
3
 
4
4
  class KindDomTest < Test::Unit::TestCase
5
5
 
6
- @@test_dom = KindDom.new(File.read(File.dirname(__FILE__) + '/flickr_rss.xml'))
6
+ @@test_dom = KindDom::Base.new(File.read(File.dirname(__FILE__) + '/flickr_rss.xml'))
7
7
 
8
8
  def test_dom_initialization
9
9
  assert_kind_of XML::Document, @@test_dom
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kind_dom
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.3
4
+ version: 0.9.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mars Hall
@@ -12,15 +12,6 @@ cert_chain: []
12
12
  date: 2008-04-07 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
- - !ruby/object:Gem::Dependency
16
- name: object_proxy
17
- version_requirement:
18
- version_requirements: !ruby/object:Gem::Requirement
19
- requirements:
20
- - - ">="
21
- - !ruby/object:Gem::Version
22
- version: 1.0.2
23
- version:
24
15
  - !ruby/object:Gem::Dependency
25
16
  name: activesupport
26
17
  version_requirement:
@@ -48,6 +39,9 @@ extensions: []
48
39
  extra_rdoc_files:
49
40
  - README
50
41
  files:
42
+ - lib/kind_dom
43
+ - lib/kind_dom/base.rb
44
+ - lib/kind_dom/object_proxy.rb
51
45
  - lib/kind_dom.rb
52
46
  - test/flickr_rss.xml
53
47
  - test/kind_dom_test.rb