Разбор XML из API с помощью Nokogiri и Rails 3

Привет, я пытаюсь разобрать XML из API веб-сайтов с помощью Nokogiri. Мне просто любопытно посмотреть, на правильном ли я пути. У меня есть контроллер, который обрабатывает синтаксический анализ, а затем я хотел бы, чтобы модель инициализировала необходимые параметры, а затем отображала их в виде простого списка в представлении. Я думал что-то вроде этого в контроллере:

def index
doc = Nokogiri::XML(open("http://www.mysomething.com/partner/api/1_0/somerandomkeynumber4b0/channel/11number/material/list/").read) 

@news = [] 

doc.css("news").each do |n|
  header = n.css("header").text
  source_name = n.css("source_name").text  
  summary = n.css("summary").text 
  url = i.css("url").text
  created_at = i.css("created_at").text
  type_of_media = i.css("type_of_media").text

  @news << News.new(
                    :header => header,)
end

а затем Модель:

class News
include ActiveModel::Validations

validates_presence_of :url, :type_of_media

attr_accessor :header, :source_name, :summary, :url, :created_at, :type_of_media  

def initialize(attributes = {})
  @header = attributes[:header]
  @source_name = attributes[:source_name]
  @summary = attributes[:summary]
  @url = attributes[:url]
  @created_at = attributes[:created_at]
  @type_of_media = attributes[:type_of_media]
end  

Вот как бы вы это сделали?! Не уверен, что я правильно думаю об этом. Может быть, у вас есть какие-нибудь советы о том, как объединить Nokogiri с чем-то еще для просмотра, например, с картами Google или чем-то еще. Прямо сейчас я получаю сообщение об ошибке
Missing template news/index with {:formats=>[:html], :handlers=>[:builder, :rjs, :erb, :rhtml, :rxml], :locale=>[:en, :en]} in view paths

Заранее спасибо!

@noodle: Итак:

  @news = doc.css('query').map do |n|
  h = {}
  %w(header source_name summary url created_at type_of_media).each do |key|
   h[key.to_sym] = n.css(key).text
  end
 News.new(h)
end 

Равно:

@news = [] 

doc.css("news").each do |n|
  header = n.css("header").text
  source_name = n.css("source_name").text  
  summary = n.css("summary").text 
  url = i.css("url").text
  created_at = i.css("created_at").text
  type_of_media = i.css("type_of_media").text

  @news << News.new(
                :header => header,)
end

Я правильно вас понял?! Что касается шаблона, я обнаружил проблему. Это была небольшая опечатка. Ваше здоровье!


person Tim    schedule 12.01.2011    source источник
comment
Да, это эквивалентно. Это не обязательно так ясно, но позволяет избежать повторения условий поиска три раза. Вы перепутали i с n в своем последнем примере, но это достаточно близко :)   -  person noodl    schedule 12.01.2011
comment
@noodl: Да, я действительно пропустил это, кажется :). И все же последний вопрос. В этой строке @news = doc.css('query') ‹- здесь должен быть указан запрос или фактический запрос?? Большое спасибо за ваши отличные ответы.   -  person Tim    schedule 13.01.2011
comment
Ok. Но тогда я немного смущен. В моем первом примере я сделал doc.css(news).each do |n| и теперь я должен просто сделать: @news = doc.css('news').map do |n| тогда? Какой должна быть эквивалентность, я думаю? Потому что вы не имеете в виду sql-запрос?   -  person Tim    schedule 13.01.2011


Ответы (1)


Вы действительно задаете два вопроса здесь ..

В порядке ли мой xml -> parse -> заполнить конвейер?

Да, в значительной степени. Поскольку в вашем блоке .each нет условной логики, было бы чище сделать это следующим образом:

@news = doc.css('query').map do |n|
  #...
  News.new(:blah => blah, ...)
end

.. но это второстепенный момент.

ИЗМЕНИТЬ

Вы можете сэкономить время на наборе текста, инициализировав хэш из проанализированного xml, а затем передав его в Model.new, например:

@news = doc.css('query').map do |n|
  h = {}
  h[:header] = n.css('header').text
  # ...
  News.new(h)
end

ИЗМЕНИТЬ 2

Или еще короче..

@news = doc.css('query').map do |n|
  h = {}
  %w(header source_name summary url created_at type_of_media).each do |key|
    h[key.to_sym] = n.css(key).text
  end
  News.new(h)
end

На самом деле #inject можно было бы сделать еще короче, но я думаю, что это было бы немного запутанно.

Почему рельсы не могут найти мой шаблон представления?

Не знаю, есть такой? Вы не дали достаточно подробностей, чтобы ответить на эту часть.

person noodl    schedule 12.01.2011
comment
Спасибо за ваш полезный отзыв. Что касается ошибки, которую я делаю так: rooting :to =› - person Tim; 12.01.2011
comment
@Tim: Похоже, тебя там отрезали. Вместо этого попробуйте обновить свой вопрос. - person noodl; 12.01.2011
comment
У кого-нибудь есть предложения, как я не могу отобразить ответ xml в своем браузере??! Я могу распечатать объект xml to_s и получить вывод в консоли, но не отображать его в моем представлении. Смущенный! заранее спасибо - person Tim; 15.01.2011
comment
Извините, @Tim, я только что увидел ваш комментарий, когда вы приняли мой ответ. Вы уже решили проблему с дисплеем? - person noodl; 19.01.2011
comment
Да, спасибо за вашу помощь. Мне удалось найти решение. Спасибо! - person Tim; 20.01.2011