Vytvoření jednoduché RSS čtečky pomocí XSLT

Pachollini, 5. července 2004, 13:55

Nemohu si nějak pomoci, ale některé články na Intervalu.cz mne poslední dobou provokují. (Jinak ovšem považuji Interval.cz za nejlepší webový magazín pro kodéry v našich zemích.) Naposledy se taková provokace podařila Petru Hellerovi článkem PHP pro pokročilé - ICONV a RSS čtečka.

Článek má podle mne dvě zásadní chyby. Za prvé nepříliš šikovně demonstruje funkčnost knihovny iconv, protože k ukázce jejího použití přidává asi 100 řádků kódového balastu. (Navíc ve skriptu vůbec neošetřuje případ, kdy mají vstupní parametry funkce iconv() jiné hodnoty než jsou specifikované v hlavičce XML dokumentu, nehledě k případu, kdy specifikace kódování chybí – což klidně může, pokud je dokument v UTF-8.)

Za druhé nabízí IMHO naprosto špatný postup, jak na RSS. Připadá mi trochu jako snaha jet automobilové závody traktorem. Předvedené řešení má jedinou výhodu: lze ho použít i na serveru bez podpory zpracování XML. Ta má v PHP kromě dalších tři základní podoby: XML parser, DOM XML a XSLT. Parser je poměrně „nízkoúrovňová“ metoda, která se myslím hodí hlavně na jednorázové, jednoúčelové a rychlé zpracování XML dokumentu. Mnohem sofistikovanější metody nabízí modul DOM XML, který umožňuje snadný přístup k jakékoliv části XML dokumentu, jeho modifikaci, umí XPath dotazy a navíc (jak je zřejmé již z názvu) jde o implementaci standardu DOM, takže co se tady naučíš, v JavaScriptu, Javě, ASP, a dalších jazycích jako když najdeš. Poslední uvedená technologie, XSLT slouží k převodu XML dokumentu na jiný dokument, nejčastěji XML, ale v zásadě na jakýkoliv textový dokument, např. CSV. Zájemcům o úvod do XML doporučuji seriál Jakuba Havla o XML, který vycházel na Živě. Co se týče podpory na serverech, podle mých zkušeností jsou dnes již standardně dostupné i moduly DOM XML a XSLT (ale přicházím do styku pouze s komerčními hostingy), instalaci PHP bez XML parseru jsem ještě neviděl.

O svém nadšení pro technologii XSLT jsem už psal, takže celkem nepřekvapivě zkusím demonstrovat jak na RSS efektivněji. Pokud váš webhoster XSLT nepodporuje, zatlačte na něj. Slibuji, že nebudete litovat vynaloženého úsilí. Pokud o XSLT nic nevíte, nezoufejte a přečtěte si seriál Petra Břízy Kompletní průvodce XSLT na Intervalu.cz, zabruste na skvělý web Jiřího Koska, podívejte se na ZVON a jistě budete za chvíli ve jmenném prostoru http://www.w3.org/1999/XSL/Transform jako doma.

Tak tedy: úplně jednoduchá čtečka RSS s využitím XSLT

Samotné vyvolání XSLT transformace vyžaduje v PHP několik příkazů, proto se vyplatí vytvořit si na ně jednoduchou funkci (ta je mimochodem i základem Seků, ale o tom někdy příště):

function xslt_transform( 
    // vrátí kód vytvořený xslt transformací podle dané šablony
  $xml, // řetězec
  $stylesheet, // cesta k souboru
  $params=array(), // další parametry v poli
  $pretty=true, // zachovat whitespace
  $replace_ent=true 
    /* změnit tvar & amp;ent; na & ent;
    hodí se při převodu XML na HTML pokud nechceme 
    deklarovat všechny HTML entity */ 
  )
{
@$stylesheet=implode("",file($stylesheet)); // načte XSLT stylesheet
$arguments = array('/_xml' => $xml, '/_xsl' => $stylesheet );
  // nastaví parametry pro volání procesoru
$xh = xslt_create(); // vytvoří procesor
xslt_set_base( $xh, 'file://'.__FILE__); 
  /* nastaví výchozí cestu; je třeba pokud v XSLT
   využíváme další XML dokumenty pomocí funkce document() 
  a máme starší verzi php */
$result=xslt_process($xh, 'arg:/_xml', 'arg:/_xsl', NULL, 
  $arguments, $params); // provede transformaci
xslt_free($xh); // odstraní parser
if($result)
  {
  if($replace_ent)$result=
    preg_replace("/<([[:alnum:]]+);/i","<\\1;",$result); 
    // převede entity
  if(!$pretty) $result=preg_replace("/>[[:space:]]*</",
    "><",$result); // vypustí whitespace
  return $result; // vrátí výsledek
  }
}

Pro převod RSS do XML požijeme následující XSLT styl (pro zjednodušení předpokládáme verzi RSS 0.91):

<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method = "xml"  version="1.0" 
  omit-xml-declaration="yes" indent="yes"  />
  
  <xsl:template match="/">
    <xsl:apply-templates select="rss/channel"/>
  </xsl:template>
  
  <xsl:template match="channel">
    <div class="channel">
      <h2>
        <a href="{link}"><xsl:value-of select="title"/></a>
      </h2>
      <xsl:apply-templates select="image|description|item"/>
    </div>
  </xsl:template>
  
  <xsl:template match="image">
    <img src="{url}" title="{title}" alt="{title}" 
      width="{width}" height="{height}"/>
  </xsl:template>
  
  <xsl:template match="description">
    <p class="description">
      <xsl:value-of select="text()"/>
    </p>
  </xsl:template>
  
  <xsl:template match="item">
    <div class="item">
      <h3>
        <a href="{link}">
          <xsl:value-of select="title"/>
        </a>
      </h3>
      <p><xsl:value-of select="description"/></p>
    </div>
  </xsl:template>
</xsl:stylesheet>

A konečně skript, který načte RSS zdroje a vypíše je:

<?
$mojekanaly=array(
  "http://seky.nahory.net/seky.rss",
  "http://cyber.law.harvard.edu/blogs/gems/tech/sampleRss091.xml"); 
    // seznam zdrojů
for($i=0;$i<count($mojekanaly);$i++)
  {
  $file=@implode("\n",file($mojekanaly[$i])); // načtení zdroje
  if($file)
    {
    preg_match("/\<\?xml[^>]+encoding=[\"']([a-zA-Z0-9\-]+)[\"']/i",
      $file, $pole); // zjištění kódování
    $charset=$pole[1]?$pole[1]:"utf-8"; 
      // pokud nebylo uvedeno, použije se utf-8
    $charset=preg_replace("/windows\-/i","CP",$charset); 
      // pokud je windows, převede argument pro funkci iconv()
    if(strtolower($charset)!="utf-8")
      {
      $file=iconv($charset."//TRANSLIT","utf-8",$file); 
        // převede se na utf-8
      $file=preg_replace(
        "/\<\?xml([^>]+)(encoding=[\"']([a-zA-Z0-9\-]+)[\"'])/i", 
        "<?xml\\1", $file); // odstraní údaj o kódování z xml
      }
    $vysledek=xslt_transform($file,"stylesheet.xsl"); 
      // provede xslt transormaci
    if($vysledek) echo $vysledek; 
      // pokud proběhla správně, vypíše výsledek
    else echo"<div>Nepodařilo se provést transformaci zdroje: ".
      $mojekanaly[$i]."</div>".$file;
    }
  else echo"<div>Nepodařilo se načíst zdroj: ".
    $mojekanaly[$i]."</div>";
  }
?>

K dispozi je ukázka provedení a zazipovaný balíček ke stažení.

Toť vše, dneska to byl opravdu jen takový sek.

Co vy na to?

[1] Fred

, 6. července 2004, 20:35

Zkusil jsem do toho nacpat 164 feedů ze čtečky - Perfektní věcička , akorát , že se to na některých kanálech sekne , třeba václavák nebo http://www.9rules.com/whitespace/index.xml složí Firefoxe do žluté obrazovky (). A pak

třeba http://www.scottandrew.com/feeds/scottandrew.xml

taky vypadá děsivě kvůli tagům , takže použití nic moc , ale trochu mě to začíná nutit podívat se xslt na zoubek . Mimochodem konečně jsem díky Vašemu blogu pochopil , proč na některých webech nejde ve Firefoxu middleclick , je to na webech takto transformovaných , zvláštní . Jsem tu

myslím třetí den a moc se mi u Vás líbí forma i obsah , díky

[2] Děkuji ;-)

Petr Bříza, 6. července 2004, 23:42

Vážně děkuji že jste světu ukázal, jak na to :))) XML a XSLT jsou úžasné technologie, sice mají své mouchy, ale nic není dokonalé. To je dobře, že se snažíte stejně jako já tyto jazyky přiblížit více lidem, protože kdyby se více používaly, svět by byl krásnější a barevnější, a lidi by se více usmívaly a jejich úsměvy by byly uzavřeny XML tagy poctivě z obou stran :-) uááá... jdu spát.

[3]

Petr Bříza, 6. července 2004, 23:44

Ježíš to je hrubka.. lidi by se více usmívaly... chtěl jsem samozřejmě napsat člověky by se více usmívaly .-)

[4] občasná nefunkčnost

pachollini, 7. července 2004, 13:03

[ 1 ] Mým cílem vůbec nebylo vytvořit fukční RSS čtečku, protože pak bych musel ošetřit různé verze RSS, chyby atd., je to jen ukázka, jak se na to dá jít. (Nicméně zrovna ošetření verzí RSS je v XSLT velmi triviální.)

Ale děkuji za Vaše uznaní, velmi mne těší. A pokud se najde jeden člověk, který se díky mému seku začne zabývat XSLT, budu dokonale spokojen.

[ 2 ] Těší mne, že jsme stejné krevní skupiny. Až to bude publikovatelné, zveřejním všech 7kb PHP kódu, který tvoří tento weblog a XSLT styly k tomu ;-)

[5] Díky!

panmayer, 29. prosince 2004, 14:05

Díky, díky, díky! Super článek.

[6] Update

Pachollini, 15. dubna 2005, 18:47

Začal jsem čtečku doopravdy používat, výsledek je vidět na http://seky.nahory.net/tools/rss-ctecka/ Tamtéž je odkaz na upravený zdrojový kód a v něm na vylepšený XSL stylesheet.

[7] buy cialis

HsvsRsvsesv, 31. března 2008, 03:19 http://groups.google.com/group/cialis-20

Přidat komentář

Vaše komentáře jsou vítány. Titulek, jméno, e-mail a odkaz na web nemusíte vyplňovat, nechcete-li. Odkaz na předcházející komentář utvoříte tak, že uvedete jeho číslo v hranatých závorkách. HTML tagy nejsou podporovány.

Kvůli ochraně proti spamu bude komentář přidán až po kontrole. Komentáře necenzuruji, vyhazuji jenom spam, vulgarismy a osobní útoky.

Aktuální Seky

.