2010-12-10 69 views
2

J'ai cherché sans fin pour une solution à cela et je pensais que je l'avais résolu quand j'ai eu une image à afficher. Cependant, la vignette était seulement celle stockée dans l'élément racine. Tout simplement cela fonctionne:Ruby, en utilisant Nokogiri et médias: thumbnail

rss = Nokogiri::XML(open('http://newsrss.bbc.co.uk/rss/newsonline_uk_edition/front_page/rss.xml')) 
@news = rss.xpath('//item').map do |i| 
    { 
    'title'  => i.xpath('title').text, 
    'link'  => i.xpath('link').text, 
    'description' => i.xpath('description').text, 
    'thumbnail' => i.xpath('//media:thumbnail').attr('url') 
    } 
end 

Mais l'édition des médias: la vignette pour référence cet élément semble casser:

{ 
    'title'  => i.xpath('title').text, 
    'link'  => i.xpath('link').text, 
    'description' => i.xpath('description').text, 
    'thumbnail' => i.xpath('media:thumbnail').attr('url') 
} 

Je ne comprends pas pourquoi que les deux éléments sont identiques. Tout pointeur dans la bonne direction serait apprécié.

Merci!

+0

Sans l'échantillon d'entrée et la question d'expression XPath, il ne s'agit pas d'une question 'xpath', mais d'une question de méthode de classe de langage spécifique (ruby). –

Répondre

1

Votre code se casse au premier élément qui n'a pas d'élément enfant miniature. Essayez ceci:

@news = rss.xpath('//item').map do |i| 
    thumb = i.at_xpath('media:thumbnail').attr('url') if i.at_xpath('media:thumbnail') 
    { 
    'title' => i.at_xpath('title').text, 
    'link' => i.at_xpath('link').text, 
    'description' => i.at_xpath('description').text, 
    'thumbnail' => thumb 
    } 
end 

Maintenant thumbnail sera soit l'URL si elle existe ou nil si elle ne fonctionne pas.

+0

Hey! Merci beaucoup pour cela, je pensais qu'il y avait un attribut de vignette pour chacun mais évidemment pas, bonne solution et tout fonctionne parfaitement maintenant: D –

+0

Juste au cas où quelqu'un trouverait cela à l'avenir, je devais ajouter: à moins que! Thumb.nil ? \t thumb = 'missing.jpg' \t fin –

+0

Ceci pourrait aussi être écrit plus court que 'thumbnail' => thumb || 'missing.jpg' –

0

A titre de comparaison, voici quelques autres façons d'accéder aux noeuds en utilisant Nokogiri:

require 'ap' 
require 'open-uri' 
require 'nokogiri' 

rss = Nokogiri::XML(open('http://newsrss.bbc.co.uk/rss/newsonline_uk_edition/front_page/rss.xml')) 

# check for parsing errors... 
puts "Errors exist" if (rss.errors.any?) 

# use CSS accessors for simplicity... 
news = rss.search('item').map { |i| 

    # use CSS's namespace wildcard... 
    thumbnail = i.at('media|thumbnail') 
    begin 
    url = thumbnail['url'] 
    rescue 
    url = '' 
    end 
    { 
    'title'  => i.search('title').text, 
    'link'  => i.search('link').text, 
    'description' => i.search('description').text, 
    'thumbnail' => url 
    } 
} 

ap [*news[0 .. 1], *news[-2 .. -1]] 
# >> [ 
# >>  [0] { 
# >>    "title" => "Royal attack 'not down to radios'", 
# >>    "link" => "http://www.bbc.co.uk/go/rss/int/news/-/news/uk-11975280", 
# >>   "description" => "Police deny that a car carrying the Prince of Wales was caught up in student protests because of a breakdown in radio communications.", 
# >>   "thumbnail" => "http://news.bbcimg.co.uk/media/images/50372000/jpg/_50372715_010819577-1.jpg" 
# >>  }, 
# >>  [1] { 
# >>    "title" => "Pope Anglican offer 'dented ties'", 
# >>    "link" => "http://www.bbc.co.uk/go/rss/int/news/-/news/uk-11974543", 
# >>   "description" => "Britain's ambassador to the Vatican feared a backlash over the Pope's invitation to Anglicans to switch churches, according to leaked US cables.", 
# >>   "thumbnail" => "http://news.bbcimg.co.uk/media/images/48697000/jpg/_48697938_007958675-1.jpg" 
# >>  }, 
# >>  [2] { 
# >>    "title" => "Playing defence", 
# >>    "link" => "http://news.bbc.co.uk/go/rss/int/news/-/1/hi/programmes/from_our_own_correspondent/9275324.stm", 
# >>   "description" => "The friendly face of township where honeymoon bride was killed", 
# >>   "thumbnail" => "http://news.bbcimg.co.uk/media/images/50385000/jpg/_50385343_football_afp.jpg" 
# >>  }, 
# >>  [3] { 
# >>    "title" => "Newspaper review", 
# >>    "link" => "http://www.bbc.co.uk/go/rss/int/news/-/news/uk-11975338", 
# >>   "description" => "Papers reflect on attack on royal car", 
# >>   "thumbnail" => "http://news.bbcimg.co.uk/media/images/49254000/jpg/_49254932_efb006dc-dd09-47bd-8f2d-37752152f772.jpg" 
# >>  } 
# >> ] 

Notez l'utilisation du caractère générique d'espace de noms CSS. Cela peut vous faciliter la vie si vous ne vous souciez pas des espaces de noms dans le document et que vous voulez tout traiter.

+0

Merci pour cela, m'aide à réaliser combien d'options il y a, pour une raison quelconque, cela n'a pas fonctionné pour moi bien que j'étais encore obtenir des erreurs nulles. –