P°ehled Φlßnk∙ z RSS ve strßnce ASP.NET
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∙:
<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.
<%@ 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.
<%@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://interval.cz/__rss/rss.asp.
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.