Da html a rss passando per xslt
o come rubare una sezione news da un sito spacciandolo per proprio.
ecco questo dovrebbe essere il sottotitolo di questo post se il mio misero wordpress mi consentisse di aggiungere un sottotitolo ai post.
Ma come al solito andiamo con ordine…
Molto spesso mi capita di sviluppare codice, anche molto gustoso (come avrebbe detto la mia professoressa di italiano delle medie), ma di non poterlo condividere con il mondo, per il semplice motivo che c’è gente che mi paga per scriverlo e che magari potrebbe averne a male se poi ritrovasse il prodotto per cui mi ha pagato allegramente e liberamente pubblicato su questo blog.
Oggi voglio fare una piccola deroga a questa regola d’oro un po’ perchè la funzionalità di cui parlo non era proprio quella richiestami dal cliente (maledetti fraintendimenti), un po’ perchè mi sarà pagata un prezzo quasi simbolico e un po’ perchè mi va.
Vediamo allora cosa vogliamo fare:
Dato un sito che pubblica con cadenza più o meno regolare delle notizie in un pannello in una propria pagina, rubare recuperare tali news e ripubblicarle sul nostro sito sottoforma di feed rss prima e pubblicarle poi in un pannello flash.
per fare questo utilizzeremo:
- uno script php per recuperare le news dal sito “esterno”
- una trasformazione xslt per trasformare i dati recuperati al punto 1 in feed rss
- flash cs3 per creare il pannellino per visualizzarle sul nostro sito
Cominciamo dicendo che il punto 3 sarà oggetto di un prossimo post, quindi se vi interessa leggere un feed rss e pubblicarlo in flash dovrete aspettare che implementi questa funzionalità e che trovi la voglia di pubblicare un altro articolo.
detto ciò vediamo lo script php di cui al punto 1:
<?php
header ( "Content-Type: application/xml" );
$xslDoc = new DOMDocument('1.0','UTF-8');
$xslDoc->load("rss.xslt");
$xmlDoc = new DOMDocument('1.0','UTF-8');
$f=file_get_contents("http://www.[sitoremoto].com/");
@$xmlDoc->loadHTML($f);
$proc = new XSLTProcessor();
$proc->importStylesheet($xslDoc);
echo $proc->transformToXML($xmlDoc);
?>
tutto chiaro vero?
si imposta l’header corretto per un file xml (invece che application/xml su alcuni forum consigliavano di usare application/rss+xml , ma non ho notato grandi differenza fin’ora)
si istanzia un oggetto DOMDocument specificando che stiamo usando un file xml 1.0 codificato in UTF-8 e gli si carica il file che contiene la trasformazione xslt che applicheremo ai dati recuperati sul sito remoto.
si istanzia un altro oggetto DOMDocument allo stesso modo di prima solo che stavolta gli si caricano i dati provenienti dal sito remoto.
A questo punto occorre notare che la funzione file_get_contents applicata ad un indirizzo esterno al dominio su cui viene eseguito lo script funzionerà solo se è attiva la direttiva allow_url_fopen all’interno del file php.ini.
da notare che il load dei file provenienti dal sito remoto è preceduto dal carattere @ per il semplice motivo che il 99% dei siti in giro per il web contiene errori e che quindi non viene interpretato correttamento come file xml e semnza la chicciolina avreste la segnalazioni di un numero di errori variabili tra 1 e n.
Il resto va da sè: si istanzia il processore XSLT, gli si carica il foglio di stile appena preparato e gli si passa il file xml con i dati da trasformare.
Vediamo ora come si presentava l’html del sito da cui prelevare le notizie e come trasformalo con xslt.
per primo un estratto dell’html:
<div id="news"> <div id="intest_grande"><h2>News sul sito remoto</h2></div> <div class="single_news"> <h6>Roma, 16 giugno 10</h6> <h4> <a title="Link permanente a questo articolo" href="http://www.sitoremoto.it/linkarticolo" rel="bookmark">Etichetta link</a> </h4> <p>(sitoremoto.it) – bla bla bla ... <span class="more"><a title="Link permanente a questo articolo" href="http://www.sitoremoto.it/permalink" rel="bookmark">Continua »</a></span> </p> </div> <div class="single_news"> ... </div> <div class="single_news"> ... </div> </div>
questa è la parte che ci interessa, tagliando l’html che precedeva e seguiva…
abbiamo quindi una serie di div con classe single_news contenenti i dati fondamentali per la creazione del nostro feed rss. Abbiamo infatti un titolo, una descrizione e un link all’articolo ovvero gli elementi obbligatori (minimi) per costruire un feed rss valido (vedere ad esempio qui per approfondire).
vediamo ora il file xslt per trasformare questo codice xml-html in xml-rss:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes" /> <xsl:template match="/"> <rss version="2.0"> <channel> <title>Nostro sito RSS</title> <link>http://nostrosito.com/</link> <description>Nostro sitoRSS Channel</description> <xsl:apply-templates select="//div" /> </channel> </rss> </xsl:template> <xsl:template match="//div"> <xsl:if test="@class = 'single_news'"> <item> <xsl:apply-templates select="h4" /> <xsl:apply-templates select="p" /> <xsl:apply-templates select="h4/a" /> </item> </xsl:if> </xsl:template> <xsl:template match="h4/a"> <link><xsl:value-of select="@href" disable-output-escaping="yes" /></link> </xsl:template> <xsl:template match="h4"> <title><xsl:value-of select="." disable-output-escaping="yes" /></title> </xsl:template> <xsl:template match="p"> <description><xsl:value-of select="substring-before(substring(.,19),'...')" disable-output-escaping="yes" /> ... Continua</description> </xsl:template> </xsl:stylesheet>
giusto due parole su questa trasformazione xslt:
si scorrono tutti i div della pagina (<xsl:template match=”//div”>) se il nome dela classe del div è single_news ( <xsl:if test=”@class = ‘single_news’”>) si applicano i template per i tag <h4> i tag <p> e i tag <a> contenuti nei tag <h4> (rispettivamente <xsl:apply-templates select=”h4″ />, <xsl:apply-templates select=”p” />, <xsl:apply-templates select=”h4/a” />) e visto che questi elementi costituisco rispettivamente il titolo, la descrizione e il link della notizia li si racchiude nei rispettivi tag dell’rss.
il risultato? eccolo:
http://nostrosito.com/ Nostro sito RSS Channel descrizione news 1 ... Continua http://www.nostrosito.it/permalink1descrizione news 2 ... Continua http://www.nostrosito.it/permalink2
si può notare che il link della notizia punta ancora al sitoesterno, ma come importare la notizia nel nostro sito e come visualizzare il feed all’interno del pannello flash sarà argomento del prossimo articolo.
quindi…. stay tuned!
p.s. devo trovare un modo per formattare il codice in maniera corretta che così fa schifo, sì lo so…

kvadrocikl on 21 giu 2010 at 03:12 #
cant w8 to try it on my business