V tomto článku si ukážeme, jak do naší aplikace vypsat nabídku článků jiného serveru. Načteme zdroj RSS a následně jej přetransformujeme jako XML pomocí XSL šablony. Pro čtení zdrojů RSS si připravíme vlastní uživatelský prvek, který nám mimo jiné umožní snadno cachovat načtené zdroje na našem serveru.

Verzí RSS je v současnosti několik, poslední verze 2.0 doplňuje možnosti dnes zatím nejrozšířenějšího formátu 0.91, proto pro jednoduchost šablonu připravíme tak, aby byla kompatibilní s oběma formáty, i když nevyužijeme všechny možnosti novější verze. Postup přípravy a syntaxe XSLT přesahuje rozsah tohoto článku, proto jej zde neřeším. Prohlédněte si ukázku (zdrojový kód).

Příklad XSLT šablony pro zobrazení přehledu článků:

<?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“ omit-xml-declaration=“yes“ indent=“yes“ encoding=“utf-8″ media-type=“text/html; charset=utf-8″ />
  <xsl:template match=“rss/channel“>
  <a><xsl:attribute name=“href“><xsl:value-of select=“link“/></xsl:attribute><xsl:attribute name=“target“><xsl:text>top</xsl:text></xsl:attribute><xsl:value-of select=“title“/></a>
  <xsl:value-of select=“lastBuildDate“/>
  <ul>
    <xsl:for-each select=“//item“>
    <lem>
      <a><xsl:attribute name=“href“><xsl:value-of select=“link“/></xsl:attribute><xsl:attribute name=“target“><xsl:text>top</xsl:text></xsl:attribute><xsl:value-of select=“title“/></a>
  <xsl:value-of select=“description“ disable-output-escaping=“yes“ />
    </lem>
    </xsl:for-each>
  </ul>
  </xsl:template>
  <xsl:template match=“/“>
    <xsl:apply-templates/>
  </xsl:template>
</xsl:stylesheet>

Pro transformace zdrojů RSS si vytvoříme vlastní uživatelský prvek, tzv. user control.. Nejenže tak můžeme snadno přidávat do stránek naší aplikace zobrazení libovolného množství RSS zdrojů, ale výborně zde využijeme i možnosti cachování částí stránek. Přetransformovaný obsah RSS si tak na serveru můžeme cachovat třeba po dobu dvou hodin, aniž by naše aplikace musela znovu navazovat spojení se vzdáleným serverem pro stažení obsahu RSS.

Pro získání obsahu ze vzdáleného serveru využijeme třídy WebRequest a WebResponse. Pomocí nich se pokusíme navázat spojení, přečteme odpověď a metodou GetResponseStream naplníme XmlTextReader. Následně si vytvoříme nový XmlDocument, metodou Load si jej naplníme obsahem TextReaderu a již jej máme připraven jako zdroj pro transformaci pomocí vestavěného XML Controlu. Nakonec také neopomeneme korektně uzavřít WebResponse stream a XmlTextReader metodou Close(), zejména pro zamezení situace, kdy by mohlo dojít k vyčerpání systémových prostředků. Dojde-li k výjimce, jen předáme jako výsledek hodnotu null.

<%@ Control Language=“C#“ EnableViewState=“False“ Debug=“False“ %>
<%@ OutputCache Duration=“7200″ Shared=“True“ VaryByControl=“XmlParser1″ %>
<%@ Import Namespace=“System.Net“ %>
<%@ Import Namespace=“System.Xml“ %>
<script language=“C#“ runat=“server“>
private string rssurl,rssxsl;
public string RssUrl
{
  set { rssurl = value; }
}
public string RssXsl
{
  set { rssxsl = value; }
}
XmlDocument getXML(string sourceURL)
{
  try
  {
    WebRequest myRequest = WebRequest.Create(sourceURL);
    WebResponse myResponse = myRequest.GetResponse();
    XmlTextReader myReader = new XmlTextReader(myResponse.GetResponseStream());
    XmlDocument doc = new XmlDocument();
    doc.Load(myReader);
    myResponse.Close();
    myReader.Close();
    return doc;
  }
  catch(WebException e)
  {
    return null;
  }
  catch(Exception e)
  {
    return null;
  }
}
void Page_Init(object sender, System.EventArgs e)
{
  if ((rssurl != null) && (rssxsl != null))
    if ((rssurl != String.Empty) && (rssxsl != String.Empty))
      if ((XmlParser1.Document = getXML(rssurl))!=null)
        try
        {
          XmlParser1.TransformSource=rssxsl;
          XmlParser1.Visible = true;
          LblError.Visible = false;
        }
        catch (Exception ex)
        {
          LblError.Visible = true;
        }
}
</script>
<asp:Xml Id=“XmlParser1″ Visible=“false“ RunAt=“server“ />
<asp:Label Id=“LblError“ Text=“Seznam článků nelze načíst…“ RunAt=“server“ />

V tomto uživatelském prvku vidíme deklaraci cachování s volbou Shared a VaryByControl. Obsah prvku bude na serveru cachován po dobu dvou hodin v závislosti na obsahu v prvku použítém controlu XML. Pokud bychom závislost na obsahu prvku XmlParser1 neuvedli, pak by se na serveru nacachoval obsah prvního staženého RSS zdroje a všechny další části stránky, kde bychom použili tento náš prvek, by ukazovaly stejný obsah prvního RSS (začátečníkům doporučuji vyzkoušet zaměnit závislost za prvek LblError a pozorovat výsledek ve stránce). Importovány jsou potřebné prostory názvů System.Net a System.Xml a deklarovány jsou také privátní a veřejné proměnné prvku (viditelné navenek jako vlastnosti).

V obsluze události Page_Init zjistíme, zda jsou zadány potřebné parametry – vlastnosti RssUrl (adresa zdroje RSS) a RssXsl (cesta k souboru XSL šablony). Pokud jsou zadány a mají neprázdný obsah, pokusíme se provést transformaci – jako vlastnost Document pro XmlParser1 předáme výsledek funkce getXML. Není-li výsledkem stažení RSS hodnota null (tato nastane jako výsledek při zachycení výjimky ve funkci getXML), pokusíme se provést transformaci. Pokud transformace selže (chyba v syntaxi XML nebo v XSL), zachytíme výjimku a ponecháme zviditelněné chybové hlášení. Jinak zviditelníme XmlParser1 a skryjeme hlášení o chybě. Princip funkce getXML, tj. jak získat XML obsah ze vzdáleného zdroje, jsem již popsal výše.

Vytvořený uživatelský ovládací prvek pak jednoduše zařadíme do naší aplikace podle potřeby. Pro ukázku jsem připravil ASP.NET stránku, která jednoduše zobrazí obsah tří různých RSS.

<%@Page Language=“C#“ EnableViewState=“False“ EnableSessionState=“False“ Trace=“False“ Debug=“False“ %>
<%@OutputCache Duration=“360″ VaryByParam=“*“ %>
<%@Register TagPrefix=“mycode“ TagName=“RSSReader“ Src=“RSSReader.ascx“ %>
<script runat=“server“>
void Page_Load (Object sender, EventArgs e)
{
  //nic
}
</script><?xml version=“1.0″ encoding=“utf-8″ ?>
<!DOCTYPE html PUBLIC „-//W3C//DTD XHTML 1.0 Transitional//EN“ „http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd“>
<html xmlns=“http://www.w3.org/1999/xhtml“ xml:lang=“cs-CZ“ lang=“cs-CZ“ dir=“ltr“>
<head>
<meta http-equiv=“Content-type“ content=“text/html; charset=utf-8″ />
<head>
<title>RSS Demo</title>
</head>
<body>
<div style=“margin:6px;padding:6px;background-color:tomato;width:300px“>
  <mycode:RSSReader Id=“RSSRdr1″ RssUrl=“http://interval.cz/__rss/rss.asp“ RssXsl=“RSSReader.xslt“ RunAt=“server“ />
</div>
<div style=“margin:6px;padding:6px;background-color:silver;width:300px“>
  <mycode:RSSReader Id=“RSSRdr2″ RssUrl=“http://www.pixy.cz/blogg/rss/index.xml“ RssXsl=“RSSReader.xslt“ RunAt=“server“ />
</div>
<div style=“margin:6px;padding:6px;background-color:beige;width:300px“>
  <mycode:RSSReader Id=“RSSRdr3″ RssUrl = „http://static.userland.com/gems/backend/rssTwoExample2.xml“ RssXsl = „RSSReader.xslt“ RunAt=“server“ />
</div>
</body>
</html>

Ve stránce vidíme nastavení cachování, zaregistrování uživatelského prvku a připravenou „nic nevykonávající“ část script. Uživatelskému prvku je vždy nastavena vlastnost RssUrl a RssXsl – zde napevno přímo v elementu prvku, ale samozřejmě by bylo možné nastavovat vlastnosti i programově, případně generovat i prvek programově v závislosti na tom, zda uživatel vůbec chce daný RSS ve stránce vidět. Pro názornost je vždy každý prvek obalen DIVem, který má nastaven styl okraje, odsazení a barvy pozadí – obdobně byste to zřejmě provedli i ve své aplikaci.

Pro hromadné nasazení v našich aplikacích by se hodilo přepsat uživatelský ovládací prvek do serverového ovládacího prvku, aby tak byl snadno k dispozici jako rozšiřující možnost pro libovolnou aplikaci na serveru (jinak bychom museli náš uživatelský prvek nakopírovat ke každé aplikaci, což není zrovna postup, který by odpovídal vizi. .net), cachování bychom si tu však museli vyřešit vlastním způsobem (direktivu OutputCache jako v uživatelském prvku zde použít nelze).

Závěrem bych rád doplnil, že budeme jen rádi, pokud do svých aplikací zařadíte i náš RSS 2 kanál, který naleznete na adrese http://export.interval.cz/?type=rss.

Pozn. red.: Tento článek vyšel poprvé 4. 7. 2003. Původní verze článku a k němu vedené diskuse jsou vám k dispozici v ZIP archivech.

Starší komentáře ke článku

Pokud máte zájem o starší komentáře k tomuto článku, naleznete je zde.

Žádný příspěvek v diskuzi

Odpovědět