<!-- THE XML IM TRYING TO PARSE --> <channel> <title/> <link>http://localhost/drupal/view/cyloop_mobile</link> <description>cyloop mobile</description> <language>en</language> <item> <title>Kinky</title> <link>http://localhost/drupal/node/3278</link> <description> <drupal_id>3278</drupal_id> <body></body> <image>/drupal/files/kinky_thumb_3_0.jpg</image> <publishing_site>Cyloop</publishing_site> <artist_id>23631</artist_id> </description> <authored>Tue, 19 Feb 2008 18:09:25 -0500</authored> <author>diana</author> <updated>Thu, 03 Apr 2008 15:54:16 -0400</updated> </item> <item> <title>Matchbox Twenty</title> <link>http://localhost/drupal/node/3277</link> <description> <drupal_id>3277</drupal_id> <body></body> <image>/drupal/files/mbox20_thumb_1_0.jpg</image> <publishing_site>Cyloop</publishing_site> <artist_id>29222</artist_id> </description> <authored>Tue, 19 Feb 2008 18:07:03 -0500</authored> <author>diana</author> <updated>Thu, 03 Apr 2008 15:53:43 -0400</updated> </item> </channel>
# MY CONTROLLER
require 'hpricot'
require 'open-uri'
class SiteController < ApplicationController
def index
# Page title for index view.
@title = "Cyloop Mobile"
# XML url to parse.
url = 'http://cm.cyloop.com/feeds/drupal/cyloop_mobile.xml'
# Open XML wth hpricot and store it in page.
page = Hpricot.XML(open(url))
(page/:item).each do |item|
title = (item/:title).inner_html
end
end
end
<h1>Featured</h1> <ul> <li></li> </ul>
Refactorings
No refactoring yet !
Jordan Glasner
May 31, 2008, May 31, 2008 01:51, permalink
class Channel
attr_accessor :url
require 'hpricot'
def initialize(url)
@url = url
end
def xml
require 'open-uri'
@xml ||= Hpricot.XML(open(url))
end
def items
(xml/:item).map { |item_xml| Item.new(item_xml) }
end
end
def Item
require 'hpricot'
attr_accessor :xml
def initialize(xml)
@xml = xml
end
def title
(xml/:title).inner_html
end
end
class ChannelsController < ApplicationController
def index
@title = 'Cyloop Mobile'
@channel = Channel.new('http://cm.cyloop.com/feeds/drupal/cyloop_mobile.xml')
end
end
# sorry would give you erb, but I would probably lead you astray %h1 Featured - @channel.items.each do |item| %h2= item.title
Jordan Glasner
May 31, 2008, May 31, 2008 02:01, permalink
arg.. I thought would be able to edit after submitting. Ignore the above, as it has some stupid errors and zero comments...
class Channel
attr_accessor :url
require 'hpricot'
# pass a url as a string to initialize
def initialize(url)
@url = url
end
def xml
require 'open-uri'
# loads the Hpricot XML object if it hasn't already been loaded
@xml ||= Hpricot.XML(open(url))
end
def items
# map is turning the array of XML objects into an array of Items
(xml/:item).map { |item_xml| Item.new(item_xml) }
end
end
class Item
require 'hpricot'
attr_accessor :xml
# pass the item XML chunk to create a new item
def initialize(xml)
@xml = xml
end
# parses the title element from the XML chunk
def title
(xml/:title).inner_html
end
end
class ChannelsController < ApplicationController
def index
@title = 'Cyloop Mobile'
# create the channel
@channel = Channel.new('http://cm.cyloop.com/feeds/drupal/cyloop_mobile.xml')
end
end
# sorry would give you erb, but I would probably lead you astray %h1 Featured # iterate through the items array - @channel.items.each do |item| %h2= item.title
Jason Calleiro
May 31, 2008, May 31, 2008 13:03, permalink
Ok, trying to take all this in, I wouldn't have thought you would need a model since I'm not actually saving any data. and on the def initialize in the models/channel.rb how does the url get passed in to the initialized method? trying to learn, thats why i am asking all the questions.
jordan Glasner
May 31, 2008, May 31, 2008 14:47, permalink
Yeah, using models only for DB access is a common misconception. I think about anything that needs to be manipulated, and I turn those into models. Ideally, your controller is only taking user input and/or creating new objects based on your models. Do a search for "skinny controllers / fat models" for more info on leaving the heavy lifting to models.
As for initialize, when you call Model.new(args) args are passed to the initialize method of the Model. So for the Channel model, you would do
Channel.new('http://mysite.com/my.xml')
After a little more thought, it's probably best to change your controller to ItemsController as that's really what you're displaying.
So...
class ItemsController < ApplicationController
def index
@title = 'Cyloop Mobile'
# create the channel and save the items to a variable
@items = Channel.new('http://cm.cyloop.com/feeds/drupal/cyloop_mobile.xml').items
end
end
%h1 Featured # iterate through the items array - @items.each do |item| %h2= item.title
I am completely new to ruby on rails and kinda new to programming. I've hacked together some php scripts but thats it.
What i am trying to do is parse through this xml and pass the title attributes to the view.
I'm not even sure if this code will work to capture the xml, I'm guessing i need the view portion to test it out. When i view the page as it is.. it doesnt error out, so i guess thats good.
I'm using Hpricot to parse the xml.
So basically how do i capture the results of this and pass it to the view?