2015-10-29 3 views
0

Я пытаюсь разобрать открытый XML-файл данных из Интернета в мою базу данных rails. Ниже приведен код, который должен разобрать его:TypeError: неявное преобразование String в Integer

require 'rake' 
require 'open-uri' 
namespace :db do 
    task :xml_parser => :environment do 
    doc = Nokogiri::XML(open("https://dl.dropboxusercontent.com/u/21695507/openplaques/gb_20151004.xml")) 
    doc.css('plaque').each do |node| 
     children = node.children 
     Plaque.create(
     :title => children.css('title').inner_text, 
     :subject => children.css('subjects').inner_text, 
     :colour => children.css('colour').inner_text, 
     :inscription => children.css('inscription raw').inner_text, 
     :latitude => children.css('geo')["latitude"].text, 
     :longitude => children.css('geo')["longitude"].text, 
     :address => children.css('address').inner_text, 
     :organisation => children.css('organisation').inner_text, 
     :date_erected => children.css('date_erected').inner_text 
    ) 
    end 
    end 
end 

А вот схема:

create_table "plaques", force: :cascade do |t| 
    t.string "title" 
    t.string "subject" 
    t.string "colour" 
    t.text  "inscription" 
    t.string "latitude" 
    t.string "longitude" 
    t.text  "address" 
    t.text  "organisation" 
    t.string "date_erected" 
    t.datetime "created_at", null: false 
    t.datetime "updated_at", null: false 
end 

бегаю грабли БД: XML_Parser и я получаю следующее сообщение об ошибке:

TypeError: no implicit conversion of String into Integer 

Ниже это образец из файла XML, который я пытаюсь проанализировать.

<plaque uri="http://openplaques.org/plaques/4856" machine_tag="openplaques:id=4856" created_at="2010-11-26T13:58:23+00:00" updated_at="2011-06-28T17:00:01+01:00"> 
    <title>Arthur Linton blue plaque</title> 
    <subjects>Arthur Linton</subjects> 
    <colour>blue</colour> 
    <inscription> 
    <raw> 
     World Champion Cyclist 1895 lived here Arthur Linton 1872-1896 
    </raw> 
    <linked> 
     World Champion Cyclist 1895 lived here <a href="/people/2934">Arthur Linton</a> 1872-1896 
    </linked> 
    </inscription> 
    <geo reference_system="WGS84" latitude="51.7005" longitude="-3.4251" is_accurate="true" /> 
    <location> 
    <address>Sheppard's Pharmacy, 218 Cardiff Road</address> 
    <locality uri="http://0.0.0.0:3000/places/gb/areas/aberaman/plaques">Aberaman</locality> 
    <country uri="http://0.0.0.0:3000/places/gb">United Kingdom</country> 
    </location> 
    <organisation uri="http://0.0.0.0:3000/organisations/rhondda_cynon_taf_council">Rhondda Cynon Taf Council</organisation> 
    <date_erected>2009-10-26</date_erected> 
    <person uri="http://0.0.0.0:3000/people/2934">Arthur Linton</person> 
</plaque> 
+0

'children.css ('geo') [" latitude "]. Text' - это не так, как вы, по-видимому, получаете значения атрибутов. Однако я не знаю, что такое правильный апи. Это зависит от вас, чтобы узнать :) –

ответ

0

Было более простое решение, которое отлично работало!

require 'rake' 
require 'open-uri' 

namespace :db do 
    task :xml_parser => :environment do 
     doc = Nokogiri::XML(open("https://dl.dropboxusercontent.com/u/21695507/openplaques/gb_20151004.xml")) 
     doc.css('plaque').each do |node| 
       title = node.xpath("plaque").text, 
       subject = node.xpath("plaque").text, 
       colour = node.xpath("plaque").text, 
       inscription = node.xpath("plaque").text, 
       latitude = node.xpath("plaque").text, 
       longitude = node.xpath("plaque").text, 
       address = node.xpath("plaque").text, 
       organisation = node.xpath("plaque").text, 
       date_erected = node.xpath("plaque").text 

       Plaque.create(:title => title, :subject => subject, :colour => colour, :inscription => inscription, :latitude => latitude, :longitude => longitude, :address => address, :organisation => organisation, :date_erected => date_erected) 
      end 
     end 
    end 
1

Я не думаю, что ошибка в схеме или содержаниеPlace.create(...). Я думаю, именно так вы извлекаете данные из Нокигири. some_node.css("some-selector") собирается вернуть набор из нескольких узлов, соответствующих критериям. Может случиться так, что количество узлов равно 1 (или 0), поэтому ваш вызов .inner_text работает.

Я считаю, что ваш вопрос на две линии для извлечения широты и долготы:

:latitude => children.css('geo')["latitude"].text, 
:longitude => children.css('geo')["longitude"].text, 

children.css('geo') возвращает набор узлов, в данном случае это похоже на один массив [geo] элементов. Однако ваш вызов ["latitude"] похож на запрос массива для его latitude -го элемента ... что не имеет смысла. В частности,

a = ["a", "b", "c", "d"] 
a[1] # => "b" 
a["longitude"] # => what?!?, or TypeError: no implicit conversion of String into Integer 

Что бы сделать, чтобы получить ваши лат и длинные значения, сначала вытащить первый элемент из css("geo") поиска. Затем вызовите атрибуты, чтобы получить хэш атрибутов. Затем вы можете получить через строку для "latitude" и "longitude", и, наконец, вам нужно позвонить .value, чтобы получить текстовое значение. В полном объеме

:latitude => children.css('geo').first.attributes["latitude"].value, 
:longitude => children.css('geo').first.attributes["longitude"].value, 
+0

Это помогло, но следующее, что я получаю, это: NoMethorError: неопределенные атрибуты метода для nil: NilClass – bystrik

+1

@BystrikOndica: возможно, вам пора изучить некоторые навыки отладки. Получение ошибок? Осмотреть значения/переменные. Это то, что вы ожидаете от них? Если нет, то почему? Продолжайте задавать вопросы (себе) и заглядывать в состояние программы. Чтение документации также помогает. –

Смежные вопросы