2010-10-15 3 views
17

Ho il seguente XML:Analisi semplice XML con Nokogiri

<links> 

    <item> 
    <title>Title 1</title> 
    <url>http://www.example.com/url-1</url> 
    </item> 

    <item> 
    <title>Title 2</title> 
    <url>http://www.example.com/url-2</url> 
    </item> 

    <item> 
    <title>Title 3</title> 
    <url>http://www.example.com/url-3</url> 
    </item> 

</links> 

E, vorrei convertirlo in un elenco HTML:

<ul> 
    <li><a href="http://www.example.com/url-1">Title 1</a></li> 
    <li><a href="http://www.example.com/url-2">Title 2</a></li> 
    <li><a href="http://www.example.com/url-3">Title 3</a></li> 
</ul> 

Attualmente ho questo:

Controller:

require 'nokogiri' 
doc = Nokogiri::XML(...) 

@links = doc.xpath('//links/item').map do |i| 
    {'title' => i.xpath('//title'), 'url' => i.xpath('//url')} 
end 

Template:

<ul> 
    <% @links.each do |l| %> 
    <li><a href="<%= l['url'] %>"><%= l['title'] %></a></li> 
    <% end %> 
</ul> 

HTML risultante:

<ul> 
    <li><a href="http://www.example.com/url-1http://www.example.com/url-2http://www.example.com/url-3">Title 1Title 2Title 3</a></li> 
    <li><a href="http://www.example.com/url-1http://www.example.com/url-2http://www.example.com/url-3">Title 1Title 2Title 3</a></li> 
    <li><a href="http://www.example.com/url-1http://www.example.com/url-2http://www.example.com/url-3">Title 1Title 2Title 3</a></li> 
</ul> 

Che cosa sto facendo di sbagliato? C'è un modo più ottimale per farlo?

+0

Buona domanda, +1. Vedi la mia risposta per una soluzione corretta e per una spiegazione dettagliata del problema. –

risposta

27

Sostituire questo:

@links = doc.xpath('//links/item').map do |i| 
    {'title' => i.xpath('//title'), 'url' => i.xpath('//url')} 

con:

@links = doc.xpath('//links/item').map do |i| 
    {'title' => i.xpath('title'), 'url' => i.xpath('url')} 

Spiegazione:

//title 

e

//url 

sono assoluti espressioni XPath e selezionare tutti (rispettivamente) title e tutti url elementi nel documento XML.

Contrast questo con:

title 

e

url 

Questi sono relativi espressioni XPath per selezionare tutti (rispettivamente) title e url figli del solo il nodo corrente.

+0

Risposta revocata, +1, poiché presumo che tu sappia davvero di cosa stai parlando.Non conosco Xpath, e ho appena indovinato xD – Matchu

+0

@Matchu: Sì, conosco XPath e capita di essere classificato # 1 da rappresentante in questo tag. :) Ma la tua risposta è stata corretta - non è necessario eliminarlo. Non cancellarlo e prevarrà. –

+0

Grazie :) Di solito sono piuttosto schizzinoso riguardo al fatto di lasciare che una risposta sia alzata quando ci sono inganni in pochi secondi, però, dato che il mio DOC ha vinto la mia insaziabile voglia di rappresentante. Grazie comunque! Sei un gentiluomo e uno studioso: o – Matchu

6

Il problema è che Xpath //title cerca i titoli dalla radice del documento e quindi restituisce tutti i tag title. Utilizzando le ricerche Xpath title nel contesto del nodo specificato, come desiderato. Idem su url.

@links = doc.xpath('//links/item').map do |i| 
    {'title' => i.xpath('title'), 'url' => i.xpath('url')} 
end 
+0

Wow ... Ho visto il tuo undelete solo ora. Certo, il meritatissimo +1. E ho ammirato la tua spiegazione del RegEx che decide se una rappresentazione numerica è composita !!! –