我正在尝试使用nokogiri和rails 3解析iTunes中的XML文件。
这是我的代码:
itunes_top_300 = Nokogiri.HTML(open("http://itunes.apple.com/us/rss/toppodcasts/limit=300/xml"))
itunes_top_300.search('//entry').each do |podcast|
url = podcast.xpath("//[@href]]").text
return podcast.url
end
当我加载调用此方法的视图时,我得到:
未定义的方法`url'
这是我要解析的xml:
http://itunes.apple.com/us/rss/toppodcasts/limit=300/xml
提前致谢,
哈里斯
答案 0 :(得分:4)
虽然您已经声明您的代码再次运行,但我要指出代码中的一些缺陷:
您要求Nokogiri将XML RSS提要解析为HTML。你应该使用Nokogiri::XML( ... )
;没什么大不了的,也不是造成这个问题的原因。
您在每个人中使用return
。在您显示的代码中,通常会导致LocalJumpError: unexpected return
。显然,您在方法中使用此代码(您尚未向我们展示)。在块内使用return
不会退出块,而是使封闭方法返回。至于你可能想要的东西,请继续阅读:
您正在创建一个本地url
变量,但您没有使用它。
我猜你要做的就是从每个Feed中找到url
。但是,通过使用XPath //[@href]
,您实际上正在查找文档中具有href="..."
属性的每个元素。您正在为文档中的每个entry
重新找到这整套元素。 (除了由于return
声明,你提前退出。)然后,通过询问元素的text
,你将一无所获。
至于您遇到的实际错误,您试图访问podcast.url
,但Nokogiri元素没有url
方法。
根据您提供的URL提要的架构,以下是以简单和优先级递增的顺序获取文档中每个href="..."
的{{1}}属性数组的不同方法:
近直接翻译
entry/link
摆脱局部变量
urls = []
itunes_top_300.search('//entry').each do |podcast|
# Find the first element below the current one that has an href attribute
# and then get the value of that attribute
url = podcast.at_xpath(".//[@href]")['href']
# Add this url to the array
urls << url
end
# As the last statement in your method, return urls (without word 'return')
urls
使用地图清理
urls = []
itunes_top_300.search('//entry').each do |podcast|
# It's pretty clear what we're doing, so no need to name the value
# before we add it to the array
urls << podcast.at_xpath(".//[@href]")['href']
end
urls
直接询问属性
# Run through the array and convert each element to the return value
# of the block
itunes_top_300.search('//entry').map do |podcast|
podcast.at_xpath(".//[@href]")['href']
end
# If the above is the last statement of the method, the method will return the
# result of the map as the return value of the method
首先只使用XPath获取我们想要的内容
itunes_top_300.search('//entry').map do |podcast|
# Instead of getting the element, get the attribute itself
# Use `to_s` or `value` to get the text of the attribute node.
podcast.at_xpath(".//[@href]/@href").to_s
end
使用Ruby 1.9语法缩短地图调用
# Take an array of attribute nodes and get their values
itunes_top_300.xpath('//entry/link/@href').map{ |attr| attr.to_s }