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.

Comments

Write a comment... 

 

Hej, jeg har længe efter det du har lavet, men jeg kan ikke få dit eks. til at virke.
Den kommer med en fejl i linie 28:
Expected 'End'
/test/test.asp, line 28, column 29
hvor der i koden er denne linie:
Response.Write "Læst kode:" xml.responseText

Har du selv fået samme fejl?

 

Hmm, ja. Sådan går det når man piller i koden man poster uden at teste den igen. Der var røget et par tegn ud, og der var i øvrigt også en lille fejl i URL'en på det news feed jeg prøvede at læse. Begge dele skulle være rettet nu, så prøv igen.

Write a comment... 

Only Name and Comment are required fields when commenting here. If you specify your email address, everyone will be able to find it at your comment. However your email will only be directly visible when hovering over your name, and in the code behind it will not look like an email address. So the risk of bots harvesting email addresses here, should be minimal. But again, you are free to leave the email blank when commenting.

If you tick Remember me, your name, email and homepage address will be remembered and prefilled at your next visit (Uses a cookie when ticked).

Full URLs (starting with "http://" or "https://") in comment text will be converted into active links when comment has been verified by a human as not being spam. Comments that looks too much like spam, will immidiately/proactively be rejected by the system and never reach a human eye.