1

I am using an API (zillow) which returns a complex hash. A sample result is

{"xmlns:xsi"=>"http://www.w3.org/2001/XMLSchema-instance", 
 "xsi:schemaLocation"=>"http://www.zillow.com/static/xsd/SearchResults.xsd http://www.zillowstatic.com/vstatic/5985ee4/static/xsd/SearchResults.xsd", 
 "xmlns:SearchResults"=>"http://www.zillow.com/static/xsd/SearchResults.xsd", "request"=>[{"address"=>["305 Vinton St"], "citystatezip"=>["Melrose, MA 02176"]}],
 "message"=>[{"text"=>["Request successfully processed"], "code"=>["0"]}],
 "response"=>[{"results"=>[{"result"=>[{"zpid"=>["56291382"], "links"=>[{"homedetails"=>["http://www.zillow.com/homedetails/305-Vinton-St-Melrose-MA-02176/56291382_zpid/"], 
 "graphsanddata"=>["http://www.zillow.com/homedetails/305-Vinton-St-Melrose-MA-02176/56291382_zpid/#charts-and-data"], "mapthishome"=>["http://www.zillow.com/homes/56291382_zpid/"], 
 "comparables"=>["http://www.zillow.com/homes/comps/56291382_zpid/"]}], "address"=>[{"street"=>["305 Vinton St"], "zipcode"=>["02176"], "city"=>["Melrose"], "state"=>["MA"], "latitude"=>["42.466805"], 
 "longitude"=>["-71.072515"]}], "zestimate"=>[{"amount"=>[{"currency"=>"USD", "content"=>"562170"}], "last-updated"=>["06/01/2014"], "oneWeekChange"=>[{"deprecated"=>"true"}], "valueChange"=>[{"duration"=>"30", "currency"=>"USD", "content"=>"42749"}], "valuationRange"=>[{"low"=>[{"currency"=>"USD", 
 "content"=>"534062"}], "high"=>[{"currency"=>"USD", "content"=>"590278"}]}], "percentile"=>["0"]}], "localRealEstate"=>[{"region"=>[{"id"=>"23017", "type"=>"city", 
 "name"=>"Melrose", "links"=>[{"overview"=>["http://www.zillow.com/local-info/MA-Melrose/r_23017/"], "forSaleByOwner"=>["http://www.zillow.com/melrose-ma/fsbo/"],
 "forSale"=>["http://www.zillow.com/melrose-ma/"]}]}]}]}]}]}]}

I can extract a specific value using the following:

result = result.to_hash

p result["response"][0]["results"][0]["result"][0]["zestimate"][0]["amount"][0]["content"]

It seems odd to have to specify the index of each element in this fashion. Is there a simpler way to obtain a named value?

Uri Agassi
  • 36,848
  • 14
  • 76
  • 93
user1553220
  • 139
  • 1
  • 8
  • 2
    I believe that the API returns an XML, not a hash... You may be better off using XPATHs on the xml rather than parsing it into a hash – Uri Agassi Jun 04 '14 at 17:26

2 Answers2

2

It looks like this should be parsed into XML. According to the Zillow API Docs, it returns XML by default. Apparently, "to_hash" was able to turn this into a hash (albeit, a very ugly one), but you are really trying to swim upstream by using it this way. I would recommend using it as intended (xml) at the start, and then maybe parsing it into an easier to use format (like a JSON/Hash structure) later.

Nokogiri is GREAT at parsing XML! You can use the xpath syntax for grabbing elements from the dom, or even css selectors.

For example, to get an array of the "content" in every result:

response = #get xml response from zillow
results = Nokogiri::XML(response).remove_namespaces!
#using css
content_array = results.css("result content")
#same thing using xpath:
content_array = results.xpath("//result//content")

If you just want the content from the first result, you can do this as a shortcut:

content = results.at_css("result content").content
Joe Edgar
  • 872
  • 5
  • 13
  • Perfect! This is what I ended up with results = Nokogiri::XML(response).remove_namespaces! p zestimate = results.css("result zestimate amount").children().to_a[0].content.to_i – user1553220 Jun 04 '14 at 19:23
  • Based on the zillow docs page I linked to in my answer... can you just do: results.at_css("result zestimate amount").content.to_i ? – Joe Edgar Jun 05 '14 at 18:06
0

Since it is indeed XML dumped into a JSON, you could use JSONPath to query the JSON