Simple Lector de Noticias RSS en Delphi
El día de hoy estuve ocupado programando este sencillo lector RSS creado en Delphi usando el componente (VCL) TXMLDocument que nos sirve para manipular estructuras XML. La aplicación en cuestión obtiene la información de titulo, fecha y descripción desde un enlace XML con formato RSS 2.0 y realiza las siguientes operaciones:
- Remueve el código HTML de preformateo, usado comúnmente entre las etiquetas <description></description> dejando el texto plano de la descripción.
- Reemplaza las entidades HTML por los símbolos equivalentes, asi por ejemplo no encontraremos “ sino unas comillas dobles. Mira todas las entidades HTML con su equivalente dando clic aquí.
- Convierte la fecha en formato RFC822 por uno de tipo DD/MM/AAAA HH:MM:SS con su respectivo tiempo en meridiano (“a.m.” o “p.m.”) usando las funciones que desarrolle anteriormente .
![]() ![]() |
Y aquí el código fuente de la unidad principal del Form:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, xmldom, XMLIntf, ComCtrls, msxmldom, XMLDoc, StdCtrls, ExtCtrls;
type
TForm1 = class(TForm)
XMLDocument1: TXMLDocument;
ListView1: TListView;
Panel1: TPanel;
Button1: TButton;
Edit1: TEdit;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
uses
DateTimeConversion;
{$R *.dfm}
//Reemplaza todas las Entidades HTML por su equivalente
//Funcion Original en LibXmlParser por Stefan Heymann
//www.destructor.de | stefan@destructor.de
PROCEDURE ReplaceCharacterEntities (VAR Str : STRING);
VAR
Start : INTEGER;
PAmp : PChar;
PSemi : PChar;
PosAmp : INTEGER;
Len : INTEGER;
BEGIN
IF Str = '' THEN EXIT;
Start := 1;
Str := StringReplace(Str,#$A,'',[rfReplaceAll, rfIgnoreCase]);
Str := StringReplace(Str,#9,'',[rfReplaceAll, rfIgnoreCase]);
REPEAT
PAmp := StrPos (PChar (Str) + Start-1, '&#');
IF PAmp = NIL THEN BREAK;
PSemi := StrScan (PAmp+2, ';');
IF PSemi = NIL THEN BREAK;
PosAmp := PAmp - PChar (Str) + 1;
Len := PSemi-PAmp+1;
IF CompareText (Str [PosAmp+2], 'x') = 0
THEN Str [PosAmp] := CHR (StrToIntDef ('$'+Copy (Str, PosAmp+3, Len-4), 0))
ELSE Str [PosAmp] := CHR (StrToIntDef (Copy (Str, PosAmp+2, Len-3), 32));
Delete (Str, PosAmp+1, Len-1);
Start := PosAmp + 1;
UNTIL FALSE;
END;
//Extrae unicamente el Texto del HTML si es que lo tiene
FUNCTION TextFromHTML(s: string):string;
var
IsText: Boolean;
i: Integer;
begin
result := '';
IsText := true;
for i := 1 to Length(s) do begin
if s[i] = '<' then IsText := false;
if IsText then result := result + s[i];
if s[i] = '>' then IsText := true;
end;
Result := StringReplace(Result, '"', '"', [rfReplaceAll]);
Result := StringReplace(Result, ''', '''', [rfReplaceAll]);
Result := StringReplace(Result, '>', '>', [rfReplaceAll]);
Result := StringReplace(Result, '<', '<', [rfReplaceAll]);
Result := StringReplace(Result, '&', '&', [rfReplaceAll]);
Result := StringReplace(Result, ' ', ' ', [rfReplaceAll]);
end;
procedure TForm1.Button1Click(Sender: TObject);
var
StartItemNode : IXMLNode;
NodoXML : IXMLNode;
sPost, sFecha, sDescripcion: String;
begin
ListView1.Clear;
XMLDocument1.FileName := Edit1.Text;
try
XMLDocument1.Active := True;
NodoXML := XMLDocument1.DocumentElement.ChildNodes.FindNode('channel');
Form1.Caption := 'Simple lector RSS - Viendo a '+NodoXML.ChildNodes['title'].Text;
StartItemNode := XMLDocument1.DocumentElement.ChildNodes.First.ChildNodes.FindNode('item');
NodoXML := StartItemNode;
repeat
sPost := NodoXML.ChildNodes['title'].Text;
sFecha := NodoXML.ChildNodes['pubDate'].Text;
sFecha := DateTimeToStr(RFC822toDateTime(sFecha));
sDescripcion := NodoXML.ChildNodes['description'].Text;
with ListView1.Items.Add do
Begin
Caption := sPost;
ReplaceCharacterEntities(sDescripcion);
SubItems.Add(sFecha);
SubItems.Add(TextFromHTML(sDescripcion));
End;
NodoXML := NodoXML.NextSibling;
until NodoXML = nil;
except
on E: EDOMParseError do
ShowMessage('Ocurrio un Error al Leer RSS');
on E: Exception do
ShowMessage('Error!');
end;
end;
end.
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, xmldom, XMLIntf, ComCtrls, msxmldom, XMLDoc, StdCtrls, ExtCtrls;
type
TForm1 = class(TForm)
XMLDocument1: TXMLDocument;
ListView1: TListView;
Panel1: TPanel;
Button1: TButton;
Edit1: TEdit;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
uses
DateTimeConversion;
{$R *.dfm}
//Reemplaza todas las Entidades HTML por su equivalente
//Funcion Original en LibXmlParser por Stefan Heymann
//www.destructor.de | stefan@destructor.de
PROCEDURE ReplaceCharacterEntities (VAR Str : STRING);
VAR
Start : INTEGER;
PAmp : PChar;
PSemi : PChar;
PosAmp : INTEGER;
Len : INTEGER;
BEGIN
IF Str = '' THEN EXIT;
Start := 1;
Str := StringReplace(Str,#$A,'',[rfReplaceAll, rfIgnoreCase]);
Str := StringReplace(Str,#9,'',[rfReplaceAll, rfIgnoreCase]);
REPEAT
PAmp := StrPos (PChar (Str) + Start-1, '&#');
IF PAmp = NIL THEN BREAK;
PSemi := StrScan (PAmp+2, ';');
IF PSemi = NIL THEN BREAK;
PosAmp := PAmp - PChar (Str) + 1;
Len := PSemi-PAmp+1;
IF CompareText (Str [PosAmp+2], 'x') = 0
THEN Str [PosAmp] := CHR (StrToIntDef ('$'+Copy (Str, PosAmp+3, Len-4), 0))
ELSE Str [PosAmp] := CHR (StrToIntDef (Copy (Str, PosAmp+2, Len-3), 32));
Delete (Str, PosAmp+1, Len-1);
Start := PosAmp + 1;
UNTIL FALSE;
END;
//Extrae unicamente el Texto del HTML si es que lo tiene
FUNCTION TextFromHTML(s: string):string;
var
IsText: Boolean;
i: Integer;
begin
result := '';
IsText := true;
for i := 1 to Length(s) do begin
if s[i] = '<' then IsText := false;
if IsText then result := result + s[i];
if s[i] = '>' then IsText := true;
end;
Result := StringReplace(Result, '"', '"', [rfReplaceAll]);
Result := StringReplace(Result, ''', '''', [rfReplaceAll]);
Result := StringReplace(Result, '>', '>', [rfReplaceAll]);
Result := StringReplace(Result, '<', '<', [rfReplaceAll]);
Result := StringReplace(Result, '&', '&', [rfReplaceAll]);
Result := StringReplace(Result, ' ', ' ', [rfReplaceAll]);
end;
procedure TForm1.Button1Click(Sender: TObject);
var
StartItemNode : IXMLNode;
NodoXML : IXMLNode;
sPost, sFecha, sDescripcion: String;
begin
ListView1.Clear;
XMLDocument1.FileName := Edit1.Text;
try
XMLDocument1.Active := True;
NodoXML := XMLDocument1.DocumentElement.ChildNodes.FindNode('channel');
Form1.Caption := 'Simple lector RSS - Viendo a '+NodoXML.ChildNodes['title'].Text;
StartItemNode := XMLDocument1.DocumentElement.ChildNodes.First.ChildNodes.FindNode('item');
NodoXML := StartItemNode;
repeat
sPost := NodoXML.ChildNodes['title'].Text;
sFecha := NodoXML.ChildNodes['pubDate'].Text;
sFecha := DateTimeToStr(RFC822toDateTime(sFecha));
sDescripcion := NodoXML.ChildNodes['description'].Text;
with ListView1.Items.Add do
Begin
Caption := sPost;
ReplaceCharacterEntities(sDescripcion);
SubItems.Add(sFecha);
SubItems.Add(TextFromHTML(sDescripcion));
End;
NodoXML := NodoXML.NextSibling;
until NodoXML = nil;
except
on E: EDOMParseError do
ShowMessage('Ocurrio un Error al Leer RSS');
on E: Exception do
ShowMessage('Error!');
end;
end;
end.





2 Respuestas to “Simple Lector de Noticias RSS en Delphi”
Nice program but you could make a better interface something like a nice translucent square on 1 side of our screen showing the info, more precise something like sidebar and stuff.
It would be a lot more attractive for the people.
Why the fuck do you have so many comments in English?
Tal vez te convendria hacer bilingue tu sitio.
Deja un comentario...