Class: KindDom::Base
- Inherits:
-
Object
- Object
- KindDom::Base
- Defined in:
- lib/kind_dom/base.rb
Overview
KindDom provides graceful access to the the DOM of an XML document using three methods of kindness:
-
#collection_of
to select a collection of nodes -
#first_of
to select one node -
#content_for
to get node content.
The original libxml behavior of the XML document is preserved through the #dom accessor.
As a contrived example, in the controller:
@results = KindDom::Base.new(xml_data)
In the view:
<% @results.first_of('//item') do |item| -%>
<p>(This block is only executed if `item` is found.)</p>
<% item.content_for('title', '(Untitled)') do |content| -%>
<h2><%=h content %></h2>
<p>(This header will show "(Untitled)" if `title` is blank or not found.)</p>
<% end -%>
<% item.content_for('description') do |content| -%>
<p><%= item.content_for('@updated_at') {|date| "<em>#{date}</em> -- " } %>
<%=h content %></p>
<p>(This block is only executed if `description` has content.)</p>
<% end -%>
<% end -%>
Instance Attribute Summary collapse
-
#dom ⇒ Object
Returns the value of attribute dom.
-
#find_cache ⇒ Object
Returns the value of attribute find_cache.
Instance Method Summary collapse
-
#collection_of(xpath, default = nil) ⇒ Object
Retrieve a collection (Array) of DOM nodes selected by the XPath.
-
#content_for(xpath = '.', default = nil) ⇒ Object
Retrieve the contents of the first node or attribute selected by the XPath; defaults to the current node, “.”.
-
#first_of(xpath, default = nil) ⇒ Object
Retrieve the first DOM node selected by the XPath.
-
#initialize(xml_in = nil, opts = {}) ⇒ Base
constructor
A new KindDom object may be created from raw XML [string] data, or an already instantiated KindDom::Base, XML::Node or XML::Document.
Constructor Details
#initialize(xml_in = nil, opts = {}) ⇒ Base
A new KindDom object may be created from raw XML [string] data, or an already instantiated KindDom::Base, XML::Node or XML::Document.
Caches intermediate found values, before yielding to the optional block. Disable the cache with opt ‘:find_cache => false` or set #find_cache to false
If you change the XML document through the #dom accessor, then you must disable or manually sweep the cache to avoid stale XPath results.
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/kind_dom/base.rb', line 47 def initialize(xml_in=nil, opts={}) unless xml_in.nil? case when xml_in.kind_of?(KindDom::Base) @dom = xml_in.dom when xml_in.kind_of?(XML::Document), xml_in.kind_of?(XML::Node) @dom = xml_in when xml_in.kind_of?(String) if XML::Parser.respond_to?(:string) parser = XML::Parser.string(xml_in) else # for old libxml-ruby compatibility parser = XML::Parser.new parser.string = xml_in end @dom = parser.parse end end @find_cache = {} if opts[:find_cache].nil? ? true : opts[:find_cache] rescue XML::Parser::ParseError ensure return self end |
Instance Attribute Details
#dom ⇒ Object
Returns the value of attribute dom.
35 36 37 |
# File 'lib/kind_dom/base.rb', line 35 def dom @dom end |
#find_cache ⇒ Object
Returns the value of attribute find_cache.
36 37 38 |
# File 'lib/kind_dom/base.rb', line 36 def find_cache @find_cache end |
Instance Method Details
#collection_of(xpath, default = nil) ⇒ Object
Retrieve a collection (Array) of DOM nodes selected by the XPath.
Each node is returned as KindDom to support #content_for, #collection_of & #first_of.
When a block is provided, it will be called with the found collection (or default) before returning.
110 111 112 113 114 115 116 117 118 119 120 121 122 |
# File 'lib/kind_dom/base.rb', line 110 def collection_of(xpath, default=nil) # :yields: found_collection c = cache "collection_of(#{xpath})" do @dom.find(xpath).collect {|n| self.class.new(n) } end rescue NoMethodError ensure c = c.blank?||c.size<1 ? default : c if block_given? and !c.nil? return yield(c) else return c end end |
#content_for(xpath = '.', default = nil) ⇒ Object
Retrieve the contents of the first node or attribute selected by the XPath; defaults to the current node, “.”
Optional second argument is the default value to return if the DOM find fails.
When a block is provided, it will be called with the found content (or default) before returning.
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/kind_dom/base.rb', line 78 def content_for(xpath='.', default=nil) # :yields: found_content content = cache "content_for(#{xpath})" do node = case @dom.class.to_s when 'XML::Document' then # for libxml-ruby 0.5.x compatibility @dom.root.find_first(xpath) else # 'XML::Node' @dom.find_first(xpath) end case node.class.to_s when 'XML::Attr', 'LibXML::XML::Attr' then node.value else node.content end end rescue NoMethodError ensure content = content.blank? ? default : content if block_given? and !content.blank? return yield(content) else return content end end |
#first_of(xpath, default = nil) ⇒ Object
Retrieve the first DOM node selected by the XPath.
The node is returned as KindDom to support #content_for, #collection_of & #first_of.
When a block is provided, it will be called with the found node (or default) before returning.
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
# File 'lib/kind_dom/base.rb', line 131 def first_of(xpath, default=nil) # :yields: found_node n = cache "first_of(#{xpath})" do case @dom.class.to_s when 'XML::Document' then # for libxml-ruby 0.5.x compatibility @dom.root.find_first(xpath) else # 'XML::Node' @dom.find_first(xpath) end end rescue NoMethodError ensure n = n.blank? ? default : self.class.new(n) if block_given? and !n.blank? return yield(n) else return n end end |