Jeg har længe ønsket mig at kunne læse indholdet af andres XML news feeds og websider i min server-side ASP-kode. Men den litteratur jeg ligger inde med om ASP og ASP.NET udvikling har ikke været til megen hjælp. Forleden satte jeg mig så ned og søgte lidt på problemet, og for evt. andre interesserede er her så løsningen jeg kom frem til. Det skal siges at jeg på ingen måde er ekspert på området, og hvis der findes bedre metoder hører jeg meget gerne om det.
ASP og VBScript
I "gammeldags" ASP skal man have fat i objektet ServerXMLHTTP. Hvis man f.eks. vil læse indholdet af mit RSS news feed, så kan det gøres med følgende VBScript-kode:
Dim xml
Dim ok
' Lav et xmlhttp objekt:
Set xml = Server.CreateObject("MSXML2.ServerXMLHTTP")
' Åben forbindelsen:
xml.Open "GET", "http://www.rockland.dk/xml/rss.asp", False
' Send request og læs data:
xml.Send
If xml.status = 200 Then
ok = True
If ucase(trim(mid(xml.responseText,1,6))) = "XMLERR" Then
ok = False
End If
Else
ok = False
End If
If ok = False Then
' Noget gik galt:
Response.Write "xml.status: " & xml.status
Response.Write "xml.statusText: " & xml.statusText
Response.Write "ERROR: " & xml.responseText
Else
' Udskriv det læste indhold:
Response.Write "Læst kode: " & xml.responseText
End If
Det læste indhold ligger nu som en streng i xml.responseText, og man kan bruge de sædvanlige streng-rutiner, regular expressions o.lign. til at fortolke indholdet. Indholdet af den læste side kan dog også tilgås i xml.responseXML, og jeg formoder at man her har en "DOM-repræsentation" af siden som man kan "kravle rundt i" med sædvanlige DOM-rutiner. Jeg er ikke selv nået dertil at jeg har kigget på dette endnu, så om responseXML virker med HTML, eller om det kun er med rigtige XML-dokumenter (som f.eks. Atom og RSS news feed) har jeg ikke fundet ud af.
ASP.NET og C#
Her er så kode der implementerer nogenlunde tilsvarende funktionalitet i ASP.NET. Eksemplet er i C#, og princippet er afprøvet i ASP.NET 1.1 og 2.0. Koden implementerer en funktion GetContent() som tager en URL på adressen der skal læses, samt en reference til en label (comstatus) hvori en evt. fejlmeddelelse skrives. Igen, jeg er ikke ekspert her, og måske kan det gøres på en bedre måde:
protected string GetContent(string url, System.Web.UI.WebControls.Label comstatus)
{
string result = "";
System.Net.HttpWebRequest wreq = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(url);
wreq.Method = "GET";
wreq.Timeout = 3000;
System.Net.HttpWebResponse wr = (System.Net.HttpWebResponse)wreq.GetResponse();
if (wr.StatusCode == System.Net.HttpStatusCode.OK)
{
System.IO.Stream s = wr.GetResponseStream();
System.Text.Encoding enc = System.Text.Encoding.GetEncoding("utf-8");
System.IO.StreamReader readStream = new System.IO.StreamReader(s, enc);
result = readStream.ReadToEnd();
}
else
{
comstatus.Text = "Error: " + wr.StatusCode + " / " + wr.StatusDescription;
}
wr.Close();
return result;
}
I praksis...
Hvis du vil bruge ovenstående teknikker til at læse indhold fra andres sider eller news feeds for visning på dine egne sider, så skal man (udover evt. opretslovs-mæssige overvejelser) være opmærksom på at det ikke er så smart hvis andres sider læses hver gang dine sider vises. For det første er det ikke fair at duplikere alle requests mod dine sider til andres. Specielt ikke hvis dine sider er ofte besøgt. Og desuden er det heller ikke særligt venligt overfor dine brugere hvis de hver gang skal vente den ekstra tid det tager at læse de eksterne sider eller news feeds først. Vær også opmærksom på at nogle feeds er konstrueret så de maksimalt kan læses af den samme "bruger" f.eks. én gang i timen! I stedet bør man læse med et interval, og et ASP eksempel på hvordan man kan sætte det op i global.asa kan findes på ActiveDeveloper.dk. Det læste indhold kan man så vælge at gemme i en database, i en almindelig tekstfil, eller måske i simple applikations-variabler indtil der læses igen næste gang (Hvis man vælger at gemme i applikations-variabler, så skal indholdet selvfølgelig hentes igen hver gang applikationen genstartes).
Selv bruger jeg nu ovenstående til, via news feeds, at læse de seneste overskrifter fra et par venners weblogs, og linke til disse indlæg her fra siden (pt. i "Venner der blogger" boksen i højre spalte). Men der er flere ting på tegnebrættet...
Update 15/2: Via et indlæg på 9am.dk er jeg blevet opmærksom på et ASP-eksempel på html.dk der læser et XML dokument (RSS news feed), og dét ser ganske interessant ud.