ruby / rexml / xpath bug?

A

altinsel

I'm doing something I would think is very straight-forward but am
getting the strangest result. I'm wondering if anyone could help to
let me know if this is a bug or if I'm doing something I can't see..

I copied a Google Maps script from Google Maps with Rails and Ajax
straight from code. It requests a geocoding from Google and parses
the XML using rexml. When it gets to the address with 2 results, the
"each" iterator is looping through, but on the second element is
giving me info from the first. below is the script exactly.

require 'open-uri'
require 'rexml/document'

# Retrieve geocode information for all records in the Stores table
task :google_geocode => :environment do
api_key=GOOGLE_MAPS_KEY

(Store.find :all).each do |store|

puts "\nStore: #{store.name}"
puts "Source Address: #{store.full_address}"

xml=open("http://maps.google.com/maps/geo?
q=#{CGI.escape(store.full_address)}&output=xml&key=#{api_key}").read
doc=REXML::Document.new(xml)

puts "Status: "+doc.elements['//kml/Response/Status/code'].text

if doc.elements['//kml/Response/Status/code'].text != '200'
puts "Unable to parse Google response for #{store.name}"
else
doc.root.each_element('//Response') do |response|
response.each_element('//Placemark') do |place|
#there are 2 "Placemarks" in one particular "Response"
lng,lat=place.elements['Point/
coordinates'].text.split(',')
puts " Result Address: " << place.elements['//
address'].text
# the address, lat and lng come from the 1st element twice
puts " ID: " << place.attributes['id']
# .. but the 'id' is correct.
puts " Latitude: #{lat}"
puts " Longitude: #{lng}"
end # end each place
end # end each response
end # end if result == 200
end # end each store
end # end rake task

#####

What I don't understand, is that the XML for each "place" is correct,
but the place.elements['//address'] keeps finding the previous
iterations information. How can this be?

Thank you.
 
R

Robert Klemme

I'm doing something I would think is very straight-forward but am
getting the strangest result. I'm wondering if anyone could help to
let me know if this is a bug or if I'm doing something I can't see..

I copied a Google Maps script from Google Maps with Rails and Ajax
straight from code. It requests a geocoding from Google and parses
the XML using rexml. When it gets to the address with 2 results, the
"each" iterator is looping through, but on the second element is
giving me info from the first. below is the script exactly.

require 'open-uri'
require 'rexml/document'

# Retrieve geocode information for all records in the Stores table
task :google_geocode => :environment do
api_key=GOOGLE_MAPS_KEY

(Store.find :all).each do |store|

puts "\nStore: #{store.name}"
puts "Source Address: #{store.full_address}"

xml=open("http://maps.google.com/maps/geo?
q=#{CGI.escape(store.full_address)}&output=xml&key=#{api_key}").read
doc=REXML::Document.new(xml)

puts "Status: "+doc.elements['//kml/Response/Status/code'].text

if doc.elements['//kml/Response/Status/code'].text != '200'
puts "Unable to parse Google response for #{store.name}"
else
doc.root.each_element('//Response') do |response|
response.each_element('//Placemark') do |place|
#there are 2 "Placemarks" in one particular "Response"
lng,lat=place.elements['Point/
coordinates'].text.split(',')

This seems weird: you search for potential multiple elements but use
method "text" on the result. Not sure what this is going to yield but
I'd rather iterate.
puts " Result Address: " << place.elements['//
address'].text

see above
# the address, lat and lng come from the 1st element twice
puts " ID: " << place.attributes['id']
# .. but the 'id' is correct.
puts " Latitude: #{lat}"
puts " Longitude: #{lng}"
end # end each place
end # end each response
end # end if result == 200
end # end each store
end # end rake task

#####

What I don't understand, is that the XML for each "place" is correct,
but the place.elements['//address'] keeps finding the previous
iterations information. How can this be?

Hm, weird. Are you sure the XML is as expected?

Btw, you can combine searching for //Response and //Placemark in one
since you do not do anything with "Response".

Kind regards

robert
 
A

altinsel

Thank you for your reply, Robert. Here is the code with output and
puts of the XML (the Stores are coming from a local database). Does
this help?

##CODE##

require 'open-uri'
require 'rexml/document'

# Retrieve geocode information for all records in the Stores table
task :google_geocode => :environment do
api_key=GOOGLE_MAPS_KEY

(Store.find :all).each do |store|

puts "\nStore: #{store.name}"
puts "Source Address: #{store.full_address}"

xml=open("http://maps.google.com/maps/geo?
q=#{CGI.escape(store.full_address)}&output=xml&key=#{api_key}").read
doc=REXML::Document.new(xml)

puts "Status: "+doc.elements['//kml/Response/Status/code'].text

if doc.elements['//kml/Response/Status/code'].text != '200'
puts "Unable to parse Google response for #{store.name}"
else
puts doc
doc.root.each_element('//Response') do |response|
puts "****"
puts response
puts "****"
response.each_element('//Placemark') do |place|
# puts "****"
# puts place.elements['//Point'];
# puts "****"
lng,lat=place.elements['Point/
coordinates'].text.split(',')
puts " Result Address: " << place.elements['//
address'].text
puts " ID: " << place.attributes['id']
puts " Latitude: #{lat}"
puts " Longitude: #{lng}"
puts "^^^^^^^^^^^^^^^^^^^^^^^^^"
end # end each place
end # end each response
end # end if result == 200
end # end each store
end # end rake task


##OUTPUT##

rake google_geocode
(in /Users/acar/Documents/Design/Code/magicmaponrails)

Store: The Original Ron Jon Surf Shop
Source Address: 901 Central Avenue, Long Beach Island, NJ, 08008
Status: 200
<?xml version='1.0' encoding='UTF-8'?><kml xmlns='http://
earth.google.com/kml/2.0'><Response><name>901 Central Avenue, Long
Beach Island, NJ, 08008</name><Status><code>200</
code><request>geocode</request></Status><Placemark
id='p1'><address>901 Central Ave, Beach Haven, NJ 08008, USA</
address><AddressDetails Accuracy='8'
xmlns='urn:eek:asis:names:tc:ciq:xsdschema:xAL:
2.0'><Country><CountryNameCode>US</
CountryNameCode><AdministrativeArea><AdministrativeAreaName>NJ</
AdministrativeAreaName><Locality><LocalityName>Beach Haven</
LocalityName><Thoroughfare><ThoroughfareName>901 Central Ave</
ThoroughfareName></Thoroughfare><PostalCode><PostalCodeNumber>08008</
PostalCodeNumber></PostalCode></Locality></AdministrativeArea></
Country></AddressDetails><Point><coordinates>-74.107299,39.756819,0</
coordinates></Point></Placemark></Response></kml>
****
<Response><name>901 Central Avenue, Long Beach Island, NJ, 08008</
name><Status><code>200</code><request>geocode</request></
Status><Placemark id='p1'><address>901 Central Ave, Beach Haven, NJ
08008, USA</address><AddressDetails Accuracy='8'
xmlns='urn:eek:asis:names:tc:ciq:xsdschema:xAL:
2.0'><Country><CountryNameCode>US</
CountryNameCode><AdministrativeArea><AdministrativeAreaName>NJ</
AdministrativeAreaName><Locality><LocalityName>Beach Haven</
LocalityName><Thoroughfare><ThoroughfareName>901 Central Ave</
ThoroughfareName></Thoroughfare><PostalCode><PostalCodeNumber>08008</
PostalCodeNumber></PostalCode></Locality></AdministrativeArea></
Country></AddressDetails><Point><coordinates>-74.107299,39.756819,0</
coordinates></Point></Placemark></Response>
****
Result Address: 901 Central Ave, Beach Haven, NJ 08008, USA
ID: p1
Latitude: 39.756819
Longitude: -74.107299
^^^^^^^^^^^^^^^^^^^^^^^^^

Store: One of aKind Ron Jon Surf Shop
Source Address: 4151 North Atlantic Avenue, Cocoa Beach, FL, 32931
Status: 200
<?xml version='1.0' encoding='UTF-8'?><kml xmlns='http://
earth.google.com/kml/2.0'><Response><name>4151 North Atlantic Avenue,
Cocoa Beach, FL, 32931</name><Status><code>200</code><request>geocode</
request></Status><Placemark id='p1'><address>4151 N Atlantic Ave,
Cocoa Beach, FL 32931, USA</address><AddressDetails Accuracy='8'
xmlns='urn:eek:asis:names:tc:ciq:xsdschema:xAL:
2.0'><Country><CountryNameCode>US</
CountryNameCode><AdministrativeArea><AdministrativeAreaName>FL</
AdministrativeAreaName><Locality><LocalityName>Cocoa Beach</
LocalityName><Thoroughfare><ThoroughfareName>4151 N Atlantic Ave</
ThoroughfareName></Thoroughfare><PostalCode><PostalCodeNumber>32931</
PostalCodeNumber></PostalCode></Locality></AdministrativeArea></
Country></AddressDetails><Point><coordinates>-80.608106,28.356747,0</
coordinates></Point></Placemark></Response></kml>
****
<Response><name>4151 North Atlantic Avenue, Cocoa Beach, FL, 32931</
name><Status><code>200</code><request>geocode</request></
Status><Placemark id='p1'><address>4151 N Atlantic Ave, Cocoa Beach,
FL 32931, USA</address><AddressDetails Accuracy='8'
xmlns='urn:eek:asis:names:tc:ciq:xsdschema:xAL:
2.0'><Country><CountryNameCode>US</
CountryNameCode><AdministrativeArea><AdministrativeAreaName>FL</
AdministrativeAreaName><Locality><LocalityName>Cocoa Beach</
LocalityName><Thoroughfare><ThoroughfareName>4151 N Atlantic Ave</
ThoroughfareName></Thoroughfare><PostalCode><PostalCodeNumber>32931</
PostalCodeNumber></PostalCode></Locality></AdministrativeArea></
Country></AddressDetails><Point><coordinates>-80.608106,28.356747,0</
coordinates></Point></Placemark></Response>
****
Result Address: 4151 N Atlantic Ave, Cocoa Beach, FL 32931, USA
ID: p1
Latitude: 28.356747
Longitude: -80.608106
^^^^^^^^^^^^^^^^^^^^^^^^^

Store: Ron Jon Surf Shop - Sunrise
Source Address: 2610 Sawgrass Mills Circle, Sunrise, FL, 33323
Status: 200
<?xml version='1.0' encoding='UTF-8'?><kml xmlns='http://
earth.google.com/kml/2.0'><Response><name>2610 Sawgrass Mills Circle,
Sunrise, FL, 33323</name><Status><code>200</code><request>geocode</
request></Status><Placemark id='p1'><address>2610 Sawgrass Mills Cir,
Fort Lauderdale, FL 33323, USA</address><AddressDetails Accuracy='8'
xmlns='urn:eek:asis:names:tc:ciq:xsdschema:xAL:
2.0'><Country><CountryNameCode>US</
CountryNameCode><AdministrativeArea><AdministrativeAreaName>FL</
AdministrativeAreaName><Locality><LocalityName>Fort Lauderdale</
LocalityName><Thoroughfare><ThoroughfareName>2610 Sawgrass Mills Cir</
ThoroughfareName></Thoroughfare><PostalCode><PostalCodeNumber>33323</
PostalCodeNumber></PostalCode></Locality></AdministrativeArea></
Country></AddressDetails><Point><coordinates>-80.315710,26.154207,0</
coordinates></Point></Placemark></Response></kml>
****
<Response><name>2610 Sawgrass Mills Circle, Sunrise, FL, 33323</
name><Status><code>200</code><request>geocode</request></
Status><Placemark id='p1'><address>2610 Sawgrass Mills Cir, Fort
Lauderdale, FL 33323, USA</address><AddressDetails Accuracy='8'
xmlns='urn:eek:asis:names:tc:ciq:xsdschema:xAL:
2.0'><Country><CountryNameCode>US</
CountryNameCode><AdministrativeArea><AdministrativeAreaName>FL</
AdministrativeAreaName><Locality><LocalityName>Fort Lauderdale</
LocalityName><Thoroughfare><ThoroughfareName>2610 Sawgrass Mills Cir</
ThoroughfareName></Thoroughfare><PostalCode><PostalCodeNumber>33323</
PostalCodeNumber></PostalCode></Locality></AdministrativeArea></
Country></AddressDetails><Point><coordinates>-80.315710,26.154207,0</
coordinates></Point></Placemark></Response>
****
Result Address: 2610 Sawgrass Mills Cir, Fort Lauderdale, FL 33323,
USA
ID: p1
Latitude: 26.154207
Longitude: -80.315710
^^^^^^^^^^^^^^^^^^^^^^^^^

Store: Ron Jon Surf Shop - Orlando
Source Address: 5160 International Drive, Orlando, FL, 32819
Status: 200
<?xml version='1.0' encoding='UTF-8'?><kml xmlns='http://
earth.google.com/kml/2.0'><Response><name>5160 International Drive,
Orlando, FL, 32819</name><Status><code>200</code><request>geocode</
request></Status><Placemark id='p1'><address>5160 International Dr,
Orlando, FL 32819, USA</address><AddressDetails Accuracy='8'
xmlns='urn:eek:asis:names:tc:ciq:xsdschema:xAL:
2.0'><Country><CountryNameCode>US</
CountryNameCode><AdministrativeArea><AdministrativeAreaName>FL</
AdministrativeAreaName><Locality><LocalityName>Orlando</
LocalityName><Thoroughfare><ThoroughfareName>5160 International Dr</
ThoroughfareName></Thoroughfare><PostalCode><PostalCodeNumber>32819</
PostalCodeNumber></PostalCode></Locality></AdministrativeArea></
Country></AddressDetails><Point><coordinates>-81.450308,28.469598,0</
coordinates></Point></Placemark></Response></kml>
****
<Response><name>5160 International Drive, Orlando, FL, 32819</
name><Status><code>200</code><request>geocode</request></
Status><Placemark id='p1'><address>5160 International Dr, Orlando, FL
32819, USA</address><AddressDetails Accuracy='8'
xmlns='urn:eek:asis:names:tc:ciq:xsdschema:xAL:
2.0'><Country><CountryNameCode>US</
CountryNameCode><AdministrativeArea><AdministrativeAreaName>FL</
AdministrativeAreaName><Locality><LocalityName>Orlando</
LocalityName><Thoroughfare><ThoroughfareName>5160 International Dr</
ThoroughfareName></Thoroughfare><PostalCode><PostalCodeNumber>32819</
PostalCodeNumber></PostalCode></Locality></AdministrativeArea></
Country></AddressDetails><Point><coordinates>-81.450308,28.469598,0</
coordinates></Point></Placemark></Response>
****
Result Address: 5160 International Dr, Orlando, FL 32819, USA
ID: p1
Latitude: 28.469598
Longitude: -81.450308
^^^^^^^^^^^^^^^^^^^^^^^^^

Store: Ron Jon Surf Shop - Key West
Source Address: 503 Front Street`, Key West, FL, 33040
Status: 200
<?xml version='1.0' encoding='UTF-8'?><kml xmlns='http://
earth.google.com/kml/2.0'><Response><name>503 Front Street`, Key West,
FL, 33040</name><Status><code>200</code><request>geocode</request></
Status><Placemark id='p1'><address>503 Front St, Key West, FL 33040,
USA</address><AddressDetails Accuracy='8'
xmlns='urn:eek:asis:names:tc:ciq:xsdschema:xAL:
2.0'><Country><CountryNameCode>US</
CountryNameCode><AdministrativeArea><AdministrativeAreaName>FL</
AdministrativeAreaName><Locality><LocalityName>Key West</
LocalityName><Thoroughfare><ThoroughfareName>503 Front St</
ThoroughfareName></Thoroughfare><PostalCode><PostalCodeNumber>33040</
PostalCodeNumber></PostalCode></Locality></AdministrativeArea></
Country></AddressDetails><Point><coordinates>-81.805852,24.560319,0</
coordinates></Point></Placemark></Response></kml>
****
<Response><name>503 Front Street`, Key West, FL, 33040</
name><Status><code>200</code><request>geocode</request></
Status><Placemark id='p1'><address>503 Front St, Key West, FL 33040,
USA</address><AddressDetails Accuracy='8'
xmlns='urn:eek:asis:names:tc:ciq:xsdschema:xAL:
2.0'><Country><CountryNameCode>US</
CountryNameCode><AdministrativeArea><AdministrativeAreaName>FL</
AdministrativeAreaName><Locality><LocalityName>Key West</
LocalityName><Thoroughfare><ThoroughfareName>503 Front St</
ThoroughfareName></Thoroughfare><PostalCode><PostalCodeNumber>33040</
PostalCodeNumber></PostalCode></Locality></AdministrativeArea></
Country></AddressDetails><Point><coordinates>-81.805852,24.560319,0</
coordinates></Point></Placemark></Response>
****
Result Address: 503 Front St, Key West, FL 33040, USA
ID: p1
Latitude: 24.560319
Longitude: -81.805852
^^^^^^^^^^^^^^^^^^^^^^^^^

Store: Ron Jon Surf Shop - California
Source Address: 20 City Blvd., Orange, CA, 92868
Status: 200
<?xml version='1.0' encoding='UTF-8'?><kml xmlns='http://
earth.google.com/kml/2.0'><Response><name>20 City Blvd., Orange, CA,
92868</name><Status><code>200</code><request>geocode</request></
Status><Placemark id='p1'><address>20 City Blvd W, Orange, CA 92868,
USA</address><AddressDetails Accuracy='8'
xmlns='urn:eek:asis:names:tc:ciq:xsdschema:xAL:
2.0'><Country><CountryNameCode>US</
CountryNameCode><AdministrativeArea><AdministrativeAreaName>CA</
AdministrativeAreaName><Locality><LocalityName>Orange</
LocalityName><Thoroughfare><ThoroughfareName>20 City Blvd W</
ThoroughfareName></Thoroughfare><PostalCode><PostalCodeNumber>92868</
PostalCodeNumber></PostalCode></Locality></AdministrativeArea></
Country></AddressDetails><Point><coordinates>-117.892764,33.782893,0</
coordinates></Point></Placemark><Placemark id='p2'><address>20 City
Blvd E, Orange, CA 92868, USA</address><AddressDetails Accuracy='8'
xmlns='urn:eek:asis:names:tc:ciq:xsdschema:xAL:
2.0'><Country><CountryNameCode>US</
CountryNameCode><AdministrativeArea><AdministrativeAreaName>CA</
AdministrativeAreaName><Locality><LocalityName>Orange</
LocalityName><Thoroughfare><ThoroughfareName>20 City Blvd E</
ThoroughfareName></Thoroughfare><PostalCode><PostalCodeNumber>92868</
PostalCodeNumber></PostalCode></Locality></AdministrativeArea></
Country></AddressDetails><Point><coordinates>-117.891102,33.784368,0</
coordinates></Point></Placemark></Response></kml>
****
<Response><name>20 City Blvd., Orange, CA, 92868</
name><Status><code>200</code><request>geocode</request></
Status><Placemark id='p1'><address>20 City Blvd W, Orange, CA 92868,
USA</address><AddressDetails Accuracy='8'
xmlns='urn:eek:asis:names:tc:ciq:xsdschema:xAL:
2.0'><Country><CountryNameCode>US</
CountryNameCode><AdministrativeArea><AdministrativeAreaName>CA</
AdministrativeAreaName><Locality><LocalityName>Orange</
LocalityName><Thoroughfare><ThoroughfareName>20 City Blvd W</
ThoroughfareName></Thoroughfare><PostalCode><PostalCodeNumber>92868</
PostalCodeNumber></PostalCode></Locality></AdministrativeArea></
Country></AddressDetails><Point><coordinates>-117.892764,33.782893,0</
coordinates></Point></Placemark><Placemark id='p2'><address>20 City
Blvd E, Orange, CA 92868, USA</address><AddressDetails Accuracy='8'
xmlns='urn:eek:asis:names:tc:ciq:xsdschema:xAL:
2.0'><Country><CountryNameCode>US</
CountryNameCode><AdministrativeArea><AdministrativeAreaName>CA</
AdministrativeAreaName><Locality><LocalityName>Orange</
LocalityName><Thoroughfare><ThoroughfareName>20 City Blvd E</
ThoroughfareName></Thoroughfare><PostalCode><PostalCodeNumber>92868</
PostalCodeNumber></PostalCode></Locality></AdministrativeArea></
Country></AddressDetails><Point><coordinates>-117.891102,33.784368,0</
coordinates></Point></Placemark></Response>
****
Result Address: 20 City Blvd W, Orange, CA 92868, USA
ID: p1
Latitude: 33.782893
Longitude: -117.892764
^^^^^^^^^^^^^^^^^^^^^^^^^
Result Address: 20 City Blvd W, Orange, CA 92868, USA
ID: p2
Latitude: 33.784368
Longitude: -117.891102
^^^^^^^^^^^^^^^^^^^^^^^^^

Store: Ron Jon Cape Caribe Resort
Source Address: 1000 Shorewood Drive, Cape Canaveral, FL, 32920
Status: 200
<?xml version='1.0' encoding='UTF-8'?><kml xmlns='http://
earth.google.com/kml/2.0'><Response><name>1000 Shorewood Drive, Cape
Canaveral, FL, 32920</name><Status><code>200</code><request>geocode</
request></Status><Placemark id='p1'><address>1000 Shorewood Dr, Cape
Canaveral, FL 32920, USA</address><AddressDetails Accuracy='8'
xmlns='urn:eek:asis:names:tc:ciq:xsdschema:xAL:
2.0'><Country><CountryNameCode>US</
CountryNameCode><AdministrativeArea><AdministrativeAreaName>FL</
AdministrativeAreaName><Locality><LocalityName>Cape Canaveral</
LocalityName><Thoroughfare><ThoroughfareName>1000 Shorewood Dr</
ThoroughfareName></Thoroughfare><PostalCode><PostalCodeNumber>32920</
PostalCodeNumber></PostalCode></Locality></AdministrativeArea></
Country></AddressDetails><Point><coordinates>-80.598021,28.405217,0</
coordinates></Point></Placemark></Response></kml>
****
<Response><name>1000 Shorewood Drive, Cape Canaveral, FL, 32920</
name><Status><code>200</code><request>geocode</request></
Status><Placemark id='p1'><address>1000 Shorewood Dr, Cape Canaveral,
FL 32920, USA</address><AddressDetails Accuracy='8'
xmlns='urn:eek:asis:names:tc:ciq:xsdschema:xAL:
2.0'><Country><CountryNameCode>US</
CountryNameCode><AdministrativeArea><AdministrativeAreaName>FL</
AdministrativeAreaName><Locality><LocalityName>Cape Canaveral</
LocalityName><Thoroughfare><ThoroughfareName>1000 Shorewood Dr</
ThoroughfareName></Thoroughfare><PostalCode><PostalCodeNumber>32920</
PostalCodeNumber></PostalCode></Locality></AdministrativeArea></
Country></AddressDetails><Point><coordinates>-80.598021,28.405217,0</
coordinates></Point></Placemark></Response>
****
Result Address: 1000 Shorewood Dr, Cape Canaveral, FL 32920, USA
ID: p1
Latitude: 28.405217
Longitude: -80.598021
^^^^^^^^^^^^^^^^^^^^^^^^^



I'm doing something I would think is very straight-forward but am
getting the strangest result.  I'm wondering if anyone could help to
let me know if this is a bug or if I'm doing something I can't see..
I copied a Google Maps script from Google Maps with Rails and Ajax
straight from code.  It requests a geocoding from Google and parses
the XML using rexml.  When it gets to the address with 2 results, the
"each" iterator is looping through, but on the second element is
giving me info from the first.  below is the script exactly.
require 'open-uri'
require 'rexml/document'
# Retrieve geocode information for all records in the Stores table
task :google_geocode => :environment do
  api_key=GOOGLE_MAPS_KEY
    (Store.find :all).each do |store|
      puts "\nStore: #{store.name}"
      puts "Source Address: #{store.full_address}"
      xml=open("http://maps.google.com/maps/geo?
q=#{CGI.escape(store.full_address)}&output=xml&key=#{api_key}").read
      doc=REXML::Document.new(xml)
      puts "Status: "+doc.elements['//kml/Response/Status/code'].text
      if doc.elements['//kml/Response/Status/code'].text != '200'
        puts "Unable to parse Google response for #{store.name}"
      else
        doc.root.each_element('//Response') do |response|
          response.each_element('//Placemark') do |place|
            #there are 2 "Placemarks" in one particular "Response"
            lng,lat=place.elements['Point/
coordinates'].text.split(',')

This seems weird: you search for potential multiple elements but use
method "text" on the result.  Not sure what this is going to yield but
I'd rather iterate.
            puts "  Result Address: " << place.elements['//
address'].text

see above


            # the address, lat and lng come from the 1st element twice
            puts "  ID: " << place.attributes['id']
            # .. but the 'id' is correct.
            puts "  Latitude: #{lat}"
            puts "  Longitude: #{lng}"
          end # end each place
        end # end each response
      end # end if result == 200
    end # end each store
  end # end rake task

What I don't understand, is that the XML for each "place" is correct,
but the place.elements['//address'] keeps finding the previous
iterations information. How can this be?

Hm, weird.  Are you sure the XML is as expected?

Btw, you can combine searching for //Response and //Placemark in one
since you do not do anything with "Response".

Kind regards

        robert
 
A

altinsel

The funny result is the Ron Jon store in Orange, CA (second from
last)...



Thank you for your reply, Robert.  Here is the code with output and
puts of the XML (the Stores are coming from a local database).  Does
this help?

##CODE##

require 'open-uri'
require 'rexml/document'

# Retrieve geocode information for all records in the Stores table
task :google_geocode => :environment do
  api_key=GOOGLE_MAPS_KEY

    (Store.find :all).each do |store|

      puts "\nStore: #{store.name}"
      puts "Source Address: #{store.full_address}"

      xml=open("http://maps.google.com/maps/geo?
q=#{CGI.escape(store.full_address)}&output=xml&key=#{api_key}").read
      doc=REXML::Document.new(xml)

      puts "Status: "+doc.elements['//kml/Response/Status/code'].text

      if doc.elements['//kml/Response/Status/code'].text != '200'
        puts "Unable to parse Google response for #{store.name}"
      else
        puts doc
        doc.root.each_element('//Response') do |response|
          puts "****"
          puts response
          puts "****"
          response.each_element('//Placemark') do |place|
            # puts "****"
            # puts place.elements['//Point'];
            # puts "****"
            lng,lat=place.elements['Point/
coordinates'].text.split(',')
            puts "  Result Address: " << place.elements['//
address'].text
            puts "  ID: " << place.attributes['id']
            puts "  Latitude: #{lat}"
            puts "  Longitude: #{lng}"
            puts "^^^^^^^^^^^^^^^^^^^^^^^^^"
          end # end each place
        end # end each response
      end # end if result == 200
    end # end each store
  end # end rake task

##OUTPUT##

rake google_geocode
(in /Users/acar/Documents/Design/Code/magicmaponrails)

Store: The Original Ron Jon Surf Shop
Source Address: 901 Central Avenue, Long Beach Island, NJ, 08008
Status: 200
<?xml version='1.0' encoding='UTF-8'?><kml xmlns='http://
earth.google.com/kml/2.0'><Response><name>901 Central Avenue, Long
Beach Island, NJ, 08008</name><Status><code>200</
code><request>geocode</request></Status><Placemark
id='p1'><address>901 Central Ave, Beach Haven, NJ 08008, USA</
address><AddressDetails Accuracy='8'
xmlns='urn:eek:asis:names:tc:ciq:xsdschema:xAL:
2.0'><Country><CountryNameCode>US</
CountryNameCode><AdministrativeArea><AdministrativeAreaName>NJ</
AdministrativeAreaName><Locality><LocalityName>Beach Haven</
LocalityName><Thoroughfare><ThoroughfareName>901 Central Ave</
ThoroughfareName></Thoroughfare><PostalCode><PostalCodeNumber>08008</
PostalCodeNumber></PostalCode></Locality></AdministrativeArea></
Country></AddressDetails><Point><coordinates>-74.107299,39.756819,0</
coordinates></Point></Placemark></Response></kml>
****
<Response><name>901 Central Avenue, Long Beach Island, NJ, 08008</
name><Status><code>200</code><request>geocode</request></
Status><Placemark id='p1'><address>901 Central Ave, Beach Haven, NJ
08008, USA</address><AddressDetails Accuracy='8'
xmlns='urn:eek:asis:names:tc:ciq:xsdschema:xAL:
2.0'><Country><CountryNameCode>US</
CountryNameCode><AdministrativeArea><AdministrativeAreaName>NJ</
AdministrativeAreaName><Locality><LocalityName>Beach Haven</
LocalityName><Thoroughfare><ThoroughfareName>901 Central Ave</
ThoroughfareName></Thoroughfare><PostalCode><PostalCodeNumber>08008</
PostalCodeNumber></PostalCode></Locality></AdministrativeArea></
Country></AddressDetails><Point><coordinates>-74.107299,39.756819,0</
coordinates></Point></Placemark></Response>
****
  Result Address: 901 Central Ave, Beach Haven, NJ 08008, USA
  ID: p1
  Latitude: 39.756819
  Longitude: -74.107299
^^^^^^^^^^^^^^^^^^^^^^^^^

Store: One of aKind Ron Jon Surf Shop
Source Address: 4151 North Atlantic Avenue, Cocoa Beach, FL, 32931
Status: 200
<?xml version='1.0' encoding='UTF-8'?><kml xmlns='http://
earth.google.com/kml/2.0'><Response><name>4151 North Atlantic Avenue,
Cocoa Beach, FL, 32931</name><Status><code>200</code><request>geocode</
request></Status><Placemark id='p1'><address>4151 N Atlantic Ave,
Cocoa Beach, FL 32931, USA</address><AddressDetails Accuracy='8'
xmlns='urn:eek:asis:names:tc:ciq:xsdschema:xAL:
2.0'><Country><CountryNameCode>US</
CountryNameCode><AdministrativeArea><AdministrativeAreaName>FL</
AdministrativeAreaName><Locality><LocalityName>Cocoa Beach</
LocalityName><Thoroughfare><ThoroughfareName>4151 N Atlantic Ave</
ThoroughfareName></Thoroughfare><PostalCode><PostalCodeNumber>32931</
PostalCodeNumber></PostalCode></Locality></AdministrativeArea></
Country></AddressDetails><Point><coordinates>-80.608106,28.356747,0</
coordinates></Point></Placemark></Response></kml>
****
<Response><name>4151 North Atlantic Avenue, Cocoa Beach, FL, 32931</
name><Status><code>200</code><request>geocode</request></
Status><Placemark id='p1'><address>4151 N Atlantic Ave, Cocoa Beach,
FL 32931, USA</address><AddressDetails Accuracy='8'
xmlns='urn:eek:asis:names:tc:ciq:xsdschema:xAL:
2.0'><Country><CountryNameCode>US</
CountryNameCode><AdministrativeArea><AdministrativeAreaName>FL</
AdministrativeAreaName><Locality><LocalityName>Cocoa Beach</
LocalityName><Thoroughfare><ThoroughfareName>4151 N Atlantic Ave</
ThoroughfareName></Thoroughfare><PostalCode><PostalCodeNumber>32931</
PostalCodeNumber></PostalCode></Locality></AdministrativeArea></
Country></AddressDetails><Point><coordinates>-80.608106,28.356747,0</
coordinates></Point></Placemark></Response>
****
  Result Address: 4151 N Atlantic Ave, Cocoa Beach, FL 32931, USA
  ID: p1
  Latitude: 28.356747
  Longitude: -80.608106
^^^^^^^^^^^^^^^^^^^^^^^^^

Store: Ron Jon Surf Shop - Sunrise
Source Address: 2610 Sawgrass Mills Circle, Sunrise, FL, 33323
Status: 200
<?xml version='1.0' encoding='UTF-8'?><kml xmlns='http://
earth.google.com/kml/2.0'><Response><name>2610 Sawgrass Mills Circle,
Sunrise, FL, 33323</name><Status><code>200</code><request>geocode</
request></Status><Placemark id='p1'><address>2610 Sawgrass Mills Cir,
Fort Lauderdale, FL 33323, USA</address><AddressDetails Accuracy='8'
xmlns='urn:eek:asis:names:tc:ciq:xsdschema:xAL:
2.0'><Country><CountryNameCode>US</
CountryNameCode><AdministrativeArea><AdministrativeAreaName>FL</
AdministrativeAreaName><Locality><LocalityName>Fort Lauderdale</
LocalityName><Thoroughfare><ThoroughfareName>2610 Sawgrass Mills Cir</
ThoroughfareName></Thoroughfare><PostalCode><PostalCodeNumber>33323</
PostalCodeNumber></PostalCode></Locality></AdministrativeArea></
Country></AddressDetails><Point><coordinates>-80.315710,26.154207,0</
coordinates></Point></Placemark></Response></kml>
****
<Response><name>2610 Sawgrass Mills Circle, Sunrise, FL, 33323</
name><Status><code>200</code><request>geocode</request></
Status><Placemark id='p1'><address>2610 Sawgrass Mills Cir, Fort
Lauderdale, FL 33323, USA</address><AddressDetails Accuracy='8'
xmlns='urn:eek:asis:names:tc:ciq:xsdschema:xAL:
2.0'><Country><CountryNameCode>US</
CountryNameCode><AdministrativeArea><AdministrativeAreaName>FL</
AdministrativeAreaName><Locality><LocalityName>Fort Lauderdale</
LocalityName><Thoroughfare><ThoroughfareName>2610 Sawgrass Mills Cir</
ThoroughfareName></Thoroughfare><PostalCode><PostalCodeNumber>33323</
PostalCodeNumber></PostalCode></Locality></AdministrativeArea></
Country></AddressDetails><Point><coordinates>-80.315710,26.154207,0</
coordinates></Point></Placemark></Response>
****
  Result Address: 2610 Sawgrass Mills Cir, Fort Lauderdale, FL 33323,
USA
  ID: p1
  Latitude: 26.154207
  Longitude: -80.315710
^^^^^^^^^^^^^^^^^^^^^^^^^

Store: Ron Jon Surf Shop - Orlando
Source Address: 5160 International Drive, Orlando, FL, 32819
Status: 200
<?xml version='1.0' encoding='UTF-8'?><kml xmlns='http://
earth.google.com/kml/2.0'><Response><name>5160 International Drive,
Orlando, FL, 32819</name><Status><code>200</code><request>geocode</
request></Status><Placemark id='p1'><address>5160 International Dr,
Orlando, FL 32819, USA</address><AddressDetails Accuracy='8'
xmlns='urn:eek:asis:names:tc:ciq:xsdschema:xAL:
2.0'><Country><CountryNameCode>US</
CountryNameCode><AdministrativeArea><AdministrativeAreaName>FL</
AdministrativeAreaName><Locality><LocalityName>Orlando</
LocalityName><Thoroughfare><ThoroughfareName>5160 International Dr</
ThoroughfareName></Thoroughfare><PostalCode><PostalCodeNumber>32819</
PostalCodeNumber></PostalCode></Locality></AdministrativeArea></
Country></AddressDetails><Point><coordinates>-81.450308,28.469598,0</
coordinates></Point></Placemark></Response></kml>
****
<Response><name>5160 International Drive, Orlando, FL, 32819</
name><Status><code>200</code><request>geocode</request></
Status><Placemark id='p1'><address>5160 International Dr, Orlando, FL
32819, USA</address><AddressDetails Accuracy='8'
xmlns='urn:eek:asis:names:tc:ciq:xsdschema:xAL:
2.0'><Country><CountryNameCode>US</
CountryNameCode><AdministrativeArea><AdministrativeAreaName>FL</
AdministrativeAreaName><Locality><LocalityName>Orlando</
LocalityName><Thoroughfare><ThoroughfareName>5160 International Dr</
ThoroughfareName></Thoroughfare><PostalCode><PostalCodeNumber>32819</
PostalCodeNumber></PostalCode></Locality></AdministrativeArea></
Country></AddressDetails><Point><coordinates>-81.450308,28.469598,0</
coordinates></Point></Placemark></Response>
****
  Result Address: 5160 International Dr, Orlando, FL 32819, USA
  ID: p1
  Latitude: 28.469598
  Longitude: -81.450308
^^^^^^^^^^^^^^^^^^^^^^^^^

Store: Ron Jon Surf Shop - Key West
Source Address: 503 Front Street`, Key West, FL, 33040
Status: 200
<?xml version='1.0' encoding='UTF-8'?><kml xmlns='http://
earth.google.com/kml/2.0'><Response><name>503 Front Street`, Key West,
FL, 33040</name><Status><code>200</code><request>geocode</request></
Status><Placemark id='p1'><address>503 Front St, Key West, FL 33040,
USA</address><AddressDetails Accuracy='8'
xmlns='urn:eek:asis:names:tc:ciq:xsdschema:xAL:
2.0'><Country><CountryNameCode>US</
CountryNameCode><AdministrativeArea><AdministrativeAreaName>FL</
AdministrativeAreaName><Locality><LocalityName>Key West</
LocalityName><Thoroughfare><ThoroughfareName>503 Front St</...

read more »
 
M

Mark Thomas

I'm surprised it works at all with the XPaths all being absolute like
that. An XPath expression starting with '//' means start at the
document root. My guess is that you are getting both addresses each
time, and the call to text() just prints the first one.

Try './/address' or just 'address' instead.

-- Mark.
 
A

altinsel

Mark,

Thank you. The './/' syntax seems to work. (I'm very happy about
that).

Now if you don't mind I'd like to ask: as far as I understand it, the
"each_element" method should only be plucking a specific branch
("place") off the tree, and that branch is a new, stand-alone tree,
and shouldn't even have the first element's data, let alone the rest
of the tree. I even So how was that information even getting in
there?
 
R

Robert Klemme

Mark,

Thank you. The './/' syntax seems to work. (I'm very happy about
that).

I'd still rather combine the two into a single iteration.

Now if you don't mind I'd like to ask: as far as I understand it, the
"each_element" method should only be plucking a specific branch
("place") off the tree, and that branch is a new, stand-alone tree,
and shouldn't even have the first element's data, let alone the rest
of the tree. I even So how was that information even getting in
there?

http://www.w3schools.com/xpath/xpath_syntax.asp

Basically a node knows about the whole document (it knows its parent as
well). So you cannot only look down but up as well. This is not too
unusual (just think about filesystems).

Cheers

robert
 
M

Mark Thomas

Mark,

Thank you.  The './/' syntax seems to work. (I'm very happy about
that).

Now if you don't mind I'd like to ask: as far as I understand it, the
"each_element" method should only be plucking a specific branch
("place") off the tree, and that branch is a new, stand-alone tree,
and shouldn't even have the first element's data, let alone the rest
of the tree.  I even So how was that information even getting in
there?

In XPath, the prefix '//' means start from the top of the tree, not
the 'current' node or "branch".

And I agree with Robert, the code is far from ideal; there is far too
much iteration. The code could be much simpler and more efficient. See
my diatribe on this here: http://markthomas.org/2008/08/22/eschew-xpathic-iteration/

-- Mark.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,968
Messages
2,570,153
Members
46,699
Latest member
AnneRosen

Latest Threads

Top