Skip to content

Commit

Permalink
replaced Hpricot with Nokogiri
Browse files Browse the repository at this point in the history
  • Loading branch information
bhousel committed Apr 2, 2011
1 parent 979ae33 commit f718646
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 56 deletions.
10 changes: 5 additions & 5 deletions README
@@ -1,11 +1,11 @@
== amazon-ecs

Generic Product Advertising Ruby API using Hpricot. Uses Response and
Generic Product Advertising Ruby API using Nokogiri. Uses Response and
Element wrapper classes for easy access to the REST API XML output.

It is generic, so you can easily extend <tt>Amazon::Ecs</tt> to support
other not implemented REST operations; and it is also generic because it just wraps around
Hpricot element object, instead of providing one-to-one object/attributes to XML elements map.
Nokogiri element object, instead of providing one-to-one object/attributes to XML elements map.

The idea is as the API evolves, there is a change in REST XML output structure,
no updates will be required on <tt>amazon-ecs</tt> gem,
Expand Down Expand Up @@ -71,12 +71,12 @@ instead you just need to update the element path.
# return an array of Amazon::Element
authors = item.get_elements('author')

# return Hpricot::Elements object or nil if not found
# return Nokogiri::XML::NodeSet object or nil if not found
reviews = item/'editorialreview'

# traverse through Hpricot elements
# traverse through Nokogiri elements
reviews.each do |review|
# Getting hash value out of Hpricot element
# Getting hash value out of Nokogiri element
Amazon::Element.get_hash(review) # [:source => ..., :content ==> ...]

# Or to get unescaped HTML values
Expand Down
16 changes: 8 additions & 8 deletions amazon-ecs.gemspec
Expand Up @@ -2,15 +2,15 @@

Gem::Specification.new do |gem|
gem.name = %q{amazon-ecs}
gem.version = "1.2.1"
gem.date = "2011-02-23"
gem.authors = ["Herryanto Siatono"]
gem.version = "1.3.0"
gem.date = "2011-04-02"
gem.authors = ["Bryan Housel"]
gem.description = %q{Generic Amazon Product Advertising Ruby API}
gem.email = %q{herryanto@gmail.com}
gem.email = %q{bryan@7thposition.com}
gem.extra_rdoc_files = ["README"]
gem.files = [ "README", "lib/amazon/ecs.rb", "test/amazon/ecs_test.rb" ]
gem.has_rdoc = true
gem.homepage = %q{https://github.com/jugend/amazon-ecs}
gem.homepage = %q{https://github.com/bhousel/amazon-ecs}
gem.rdoc_options = ["--inline-source", "--charset=UTF-8"]
gem.require_paths = ["lib"]
gem.rubygems_version = %q{1.3.1}
Expand All @@ -21,14 +21,14 @@ Gem::Specification.new do |gem|
gem.specification_version = 2

if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
gem.add_runtime_dependency("hpricot", ">= 0.4")
gem.add_runtime_dependency("nokogiri", ">= 1.4.0")
gem.add_runtime_dependency("ruby-hmac", ">= 0.3.2")
else
gem.add_dependency("hpricot", ">= 0.4")
gem.add_dependency("nokogiri", ">= 1.4.0")
gem.add_dependency("ruby-hmac", ">= 0.3.2")
end
else
gem.add_dependency("hpricot", ">= 0.4")
gem.add_dependency("nokogiri", ">= 1.4.0")
gem.add_dependency("ruby-hmac", ">= 0.3.2")
end
end
4 changes: 2 additions & 2 deletions doc/classes/Amazon/Ecs/Response.html
Expand Up @@ -143,7 +143,7 @@ <h3 class="section-bar">Public Class methods</h3>
<pre>
<span class="ruby-comment cmt"># File lib/amazon/ecs.rb, line 109</span>
109: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">initialize</span>(<span class="ruby-identifier">xml</span>)
110: <span class="ruby-ivar">@doc</span> = <span class="ruby-constant">Hpricot</span>(<span class="ruby-identifier">xml</span>)
110: <span class="ruby-ivar">@doc</span> = <span class="ruby-constant">Nokogiri</span>(<span class="ruby-identifier">xml</span>)
111: <span class="ruby-keyword kw">end</span>
</pre>
</div>
Expand All @@ -163,7 +163,7 @@ <h3 class="section-bar">Public Instance methods</h3>

<div class="method-description">
<p>
Return Hpricot object.
Return Nokogiri::XML object.
</p>
<p><a class="source-toggle" href="#"
onclick="toggleCode('M000035-source');return false;">[Source]</a></p>
Expand Down
2 changes: 1 addition & 1 deletion doc/classes/Amazon/EcsTest.html
Expand Up @@ -169,7 +169,7 @@ <h3 class="section-bar">Public Instance methods</h3>
71: <span class="ruby-comment cmt"># test /</span>
72: <span class="ruby-identifier">reviews</span> = <span class="ruby-identifier">item</span><span class="ruby-operator">/</span><span class="ruby-value str">&quot;editorialreview&quot;</span>
73: <span class="ruby-identifier">reviews</span>.<span class="ruby-identifier">each</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">review</span><span class="ruby-operator">|</span>
74: <span class="ruby-comment cmt"># returns unescaped HTML content, Hpricot escapes all text values</span>
74: <span class="ruby-comment cmt"># returns unescaped HTML content, Nokogiri escapes all text values</span>
75: <span class="ruby-identifier">assert</span> <span class="ruby-constant">Amazon</span><span class="ruby-operator">::</span><span class="ruby-constant">Element</span>.<span class="ruby-identifier">get_unescaped</span>(<span class="ruby-identifier">review</span>, <span class="ruby-value str">'source'</span>)
76: <span class="ruby-identifier">assert</span> <span class="ruby-constant">Amazon</span><span class="ruby-operator">::</span><span class="ruby-constant">Element</span>.<span class="ruby-identifier">get_unescaped</span>(<span class="ruby-identifier">review</span>, <span class="ruby-value str">'content'</span>)
77: <span class="ruby-keyword kw">end</span>
Expand Down
2 changes: 1 addition & 1 deletion doc/classes/Amazon/Element.html
Expand Up @@ -180,7 +180,7 @@ <h3 class="section-bar">Public Class methods</h3>
268: <span class="ruby-keyword kw">return</span> <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">element</span>
269:
270: <span class="ruby-identifier">result</span> = <span class="ruby-identifier">element</span><span class="ruby-operator">/</span><span class="ruby-identifier">path</span>
271: <span class="ruby-keyword kw">if</span> (<span class="ruby-identifier">result</span>.<span class="ruby-identifier">is_a?</span> <span class="ruby-constant">Hpricot</span><span class="ruby-operator">::</span><span class="ruby-constant">Elements</span>) <span class="ruby-operator">||</span> (<span class="ruby-identifier">result</span>.<span class="ruby-identifier">is_a?</span> <span class="ruby-constant">Array</span>)
271: <span class="ruby-keyword kw">if</span> (<span class="ruby-identifier">result</span>.<span class="ruby-identifier">is_a?</span> <span class="ruby-constant">Nokogiri</span><span class="ruby-operator">::</span><span class="ruby-constant">XML</span>) <span class="ruby-operator">||</span> (<span class="ruby-identifier">result</span>.<span class="ruby-identifier">is_a?</span> <span class="ruby-constant">Array</span>)
272: <span class="ruby-identifier">parsed_result</span> = []
273: <span class="ruby-identifier">result</span>.<span class="ruby-identifier">each</span> {<span class="ruby-operator">|</span><span class="ruby-identifier">item</span><span class="ruby-operator">|</span>
274: <span class="ruby-identifier">parsed_result</span> <span class="ruby-operator">&lt;&lt;</span> <span class="ruby-constant">Element</span>.<span class="ruby-identifier">get</span>(<span class="ruby-identifier">item</span>)
Expand Down
64 changes: 25 additions & 39 deletions lib/amazon/ecs.rb
Expand Up @@ -22,7 +22,7 @@
#++

require 'net/http'
require 'hpricot'
require 'nokogiri'
require 'cgi'
require 'hmac-sha2'
require 'base64'
Expand Down Expand Up @@ -123,10 +123,12 @@ def self.send_request(opts)
class Response
# XML input is in string format
def initialize(xml)
@doc = Hpricot(xml)
@doc = Nokogiri::XML(xml)
@doc.remove_namespaces!
@doc.xpath("//*").each { |elem| elem.name = elem.name.downcase }
end

# Return Hpricot object.
# Return Nokogiri::XML::Document object.
def doc
@doc
end
Expand All @@ -153,10 +155,7 @@ def error_code

# Return an array of Amazon::Element item objects.
def items
unless @items
@items = (@doc/"item").collect {|item| Element.new(item)}
end
@items
@items ||= (@doc/"item").collect {|item| Element.new(item)}
end

# Return the first item (Amazon::Element)
Expand All @@ -166,26 +165,17 @@ def first_item

# Return current page no if :item_page option is when initiating the request.
def item_page
unless @item_page
@item_page = (@doc/"itemsearchrequest/itempage").inner_html.to_i
end
@item_page
@item_page ||= (@doc/"itemsearchrequest/itempage").inner_html.to_i
end

# Return total results.
def total_results
unless @total_results
@total_results = (@doc/"totalresults").inner_html.to_i
end
@total_results
@total_results ||= (@doc/"totalresults").inner_html.to_i
end

# Return total pages.
def total_pages
unless @total_pages
@total_pages = (@doc/"totalpages").inner_html.to_i
end
@total_pages
@total_pages ||= (@doc/"totalpages").inner_html.to_i
end
end

Expand Down Expand Up @@ -264,19 +254,19 @@ def self.sign_request(url, key)
end
end

# Internal wrapper class to provide convenient method to access Hpricot element value.
# Internal wrapper class to provide convenient method to access Nokogiri element value.
class Element
# Pass Hpricot::Elements object
# Pass Nokogiri::XML::Element object
def initialize(element)
@element = element
end

# Returns Hpricot::Elments object
# Returns Nokogiri::XML::Element object
def elem
@element
end

# Find Hpricot::Elements matching the given path. Example: element/"author".
# Returns a Nokogiri::XML::NodeSet of elements matching the given path. Example: element/"author".
def /(path)
elements = @element/path
return nil if elements.size == 0
Expand Down Expand Up @@ -307,22 +297,22 @@ def get_element(path)
end

# Get the text value of the given path, leave empty to retrieve current element value.
def get(path='')
def get(path='.')
Element.get(@element, path)
end

# Get the unescaped HTML text of the given path.
def get_unescaped(path='')
def get_unescaped(path='.')
Element.get_unescaped(@element, path)
end

# Get the array values of the given path.
def get_array(path='')
def get_array(path='.')
Element.get_array(@element, path)
end

# Get the children element text values in hash format with the element names as the hash keys.
def get_hash(path='')
def get_hash(path='.')
Element.get_hash(@element, path)
end

Expand All @@ -332,40 +322,36 @@ def attributes
end

# Similar to #get, except an element object must be passed-in.
def self.get(element, path='')
def self.get(element, path='.')
return unless element
result = element.at(path)
result = element.at_xpath(path)
result = result.inner_html if result
result
end

# Similar to #get_unescaped, except an element object must be passed-in.
def self.get_unescaped(element, path='')
def self.get_unescaped(element, path='.')
result = get(element, path)
CGI::unescapeHTML(result) if result
end

# Similar to #get_array, except an element object must be passed-in.
def self.get_array(element, path='')
def self.get_array(element, path='.')
return unless element

result = element/path
if (result.is_a? Hpricot::Elements) || (result.is_a? Array)
parsed_result = []
result.each {|item|
parsed_result << Element.get(item)
}
parsed_result
if (result.is_a? Nokogiri::XML::NodeSet) || (result.is_a? Array)
result.collect { |item| Element.get(item) }
else
[Element.get(result)]
end
end

# Similar to #get_hash, except an element object must be passed-in.
def self.get_hash(element, path='')
def self.get_hash(element, path='.')
return unless element

result = element.at(path)
result = element.at_xpath(path)
if result
hash = {}
result = result.children
Expand Down

0 comments on commit f718646

Please sign in to comment.