2012-06-22 2 views
0

Я использую Nokogiri для анализа ответа XML от last.fm. В настоящее время я возвращаю информацию, которую хочу, но не в том формате, который хотел бы. То, что я получаю, это то, что кажется одним Документом Nokogiri :: XML. То, что я хочу, это строка за <track>, которая включает название, исполнитель и URL-адрес песни. Вот образец XML:Неправильный разбор xml с помощью Nokogiri в Ruby

<lfm status="ok"> 
    <toptracks metro="Beijing" page="1" perPage="50" totalPages="10" total="500"> 
    <track rank="1"> 
     <name>Rolling in the Deep</name> 
     <duration>226</duration> 
     <listeners>33</listeners> 
     <mbid>092a88bc-af0b-4ddd-a3a1-17ad37abfccb</mbid> 
     <url> 
     http://www.last.fm/music/Adele/_/Rolling+in+the+Deep 
     </url> 
     <streamable fulltrack="0">1</streamable> 
     <artist> 
     <name>Adele</name> 
     <mbid>1de93a63-3a9f-443a-ba8a-a43b5fe0121e</mbid> 
     <url>http://www.last.fm/music/Adele</url> 
     </artist> 
     <image size="small">http://userserve-ak.last.fm/serve/34s/55125087.png</image> 
     <image size="medium">http://userserve-ak.last.fm/serve/64s/55125087.png</image> 
     <image size="large">http://userserve-ak.last.fm/serve/126/55125087.png</image> 
     <image size="extralarge"> 
     http://userserve-ak.last.fm/serve/300x300/55125087.png 
     </image> 
    </track> 
    </toptracks> 
</lfm> 

А вот код я использую:

doc = Nokogiri::HTML(open(url)) 

doc.xpath("//toptracks").each do |track| 
    song_title = track.xpath("*/name").text 
    song_lastfm_url = track.xpath("*/url").text 
    song_artist = track.xpath("*/artist/name").text 

    puts "#{song_title} - #{song_lastfm_url} - #{song_artist}" 
end 

Как я уже говорил, хотя я получаю все названия песен, а затем все песни urls, за которыми следуют все исполнители песен как один XML-документ.

ответ

2

Вы не итерируете через дорожки, как вы думаете. Попробуйте следующее:

doc.xpath('//toptracks/track').each do |track| 
    song_title, song_lastfm_url, song_artist = track.xpath('./name','./url','./artist/name').map{|x| x.text.strip} 
end 
+0

Это было. Отлично! Можете ли вы объяснить, что я делал неправильно случайно? – tvalent2

+0

Вы делали итерацию через топтаки, которые, я считаю, есть только один из них, а не toptracks/track. Кроме того, я не уверен, что должен был делать * в вашем xpath, ./ означает текущий узел (дорожка), так что ./name - это узел «name», который является дочерним по отношению к треку – pguardiario

+0

. Я нашел здесь * здесь (как в этом посте, но не совсем - http://stackoverflow.com/questions/571663/ruby-xpath-to-find-attribute). Спасибо за объяснение! – tvalent2

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