手把手教你实现RSS XML

以下是如何生成当今比较流行的RSS XML的详细示例, 描述的是如何从"大智慧"行情数据中获取数据并转化成RSS XML文件, 当然咯! 如果您想实时刷新这个RSS XML, 恐怕要去截取"大智慧"的网络数据或内存数据了, 这里我们不谈这个.
    
(代码中解释比较详细, 不再多做解释)
     
   

 unit STRService;
                  
 interface
 
 uses
   Windows, Messages, SysUtils, Classes, Graphics, Controls, SvcMgr, Dialogs,
   ExtCtrls, Contnrs, StrUtils, DB, ADODB, IniFiles, ActiveX, xmldom,
   XMLIntf, msxmldom, XMLDoc;
 
 type
   TStockDayLineKDataReader = class;
 
   TStockRSSSvc = class(TService)
     Timer1: TTimer;
     STRConn: TADOConnection;
     qryCommon: TADOQuery;
     procedure ServiceExecute(Sender: TService);
     procedure ServiceStart(Sender: TService; var Started: Boolean);
     procedure ServiceStop(Sender: TService; var Stopped: Boolean);
     procedure Timer1Timer(Sender: TObject);
   private
     { Private declarations }
     FLineKReader: TStockDayLineKDataReader;
   public
     function GetServiceController: TServiceController; override;
     { Public declarations }
     function GetWorkingPath: string;
   end;
 
   TDayLineKProperty = class
   private
     FStockID: string;
     FDate: DWORD;
     FOpen: DWORD;
     FClose: DWORD;
     FHigh: DWORD;
     FLow: DWORD;
     FTranQuantity: DWORD;
     FSum: DWORD;
   public
     constructor Create (ID: string; DateVal, OpenVal, CloseVal, HighVal, LowVal,
       QuantityVal, SumVal: DWORD);
     destructor Destroy; override;
 
     property ID: string read FStockID;
     property Date: DWORD read FDate;
     property Open: DWORD read FOpen;
     property Close: DWORD read FClose;
     property High: DWORD read FHigh;
     property Low: DWORD read FLow;
     property TranQuantity: DWORD read FTranQuantity;
     property Sum: DWORD read FSum;
   end;
 
   TStockDayLineKDataReader = class
   private
     FRSSLocation: string;
     FLocation: string;
     FSHDayLocation: string;
     FSZDayLocation: string;
     FStockList: TObjectList;
     FStockIDList: TStrings;
     FQuery: TADOQuery;
   
   protected
     procedure SetLocation (AValue: string);
     procedure Clear;
     procedure GetStockIDFiles (ABuffer: TStrings; DataPath: string);
     procedure ReadData (AFileName: string);
     procedure ClearDayLineKData;
     procedure WriteToDB (DayLineObj: TDayLineKProperty);
     function GetStockMarketInfo: string;
 
   public
     constructor Create (AQuery: TADOQuery; ALocation: string; RSSDest: string);
     destructor Destroy; override;
 
     procedure Load;
     procedure SaveToDatabase;
     procedure SaveToRSS;
 
     property Location: string read FLocation write SetLocation;
   end;
 
 
 var
   StockRSSSvc: TStockRSSSvc;
 
 implementation
 
 {$R *.DFM}
 
 procedure ServiceController(CtrlCode: DWord); stdcall;
 begin
   StockRSSSvc.Controller(CtrlCode);
 end;
 
 function TStockRSSSvc.GetServiceController: TServiceController;
 begin
   Result := ServiceController;
 end;
 
 function TStockRSSSvc.GetWorkingPath: string;
 begin
   Result := ExtractFilePath (ParamStr (0));
 end;
 
 procedure TStockRSSSvc.ServiceExecute(Sender: TService);
 begin
   while not Terminated do
   begin
     ServiceThread.ProcessRequests(True);
   end;
 end;
 
 { TDayLineKProperty }
 
 constructor TDayLineKProperty.Create(ID: string; DateVal, OpenVal, CloseVal, HighVal,
   LowVal, QuantityVal, SumVal: DWORD);
 begin
   FStockID := ID;
   FDate := DateVal;
   FOpen := OpenVal;
   FClose := CloseVal;
   FHigh := HighVal;
   FLow := LowVal;
   FTranQuantity := QuantityVal;
   FSum := SumVal;
 end;
 
 destructor TDayLineKProperty.Destroy;
 begin
 
   inherited;
 end;
 
 { TStockDayLineKDataReader }
 
 procedure TStockDayLineKDataReader.Clear;
 begin
   if Assigned (FStockList) then
     FreeAndNil (FStockList);
 end;
 
 procedure TStockDayLineKDataReader.ClearDayLineKData;
 begin
   if not Assigned (FQuery) then Exit;
   with FQuery do
   begin
     Close;
     SQL.Clear;
     SQL.Add ('DELETE * FROM db_DayLineK');
     Prepared := True;
     try
       try
         ExecSQL;
       except
         on E: Exception do raise E.Create (E.Message);
       end;
     finally
       Close;
     end; //end try_finally
   end; //end with_do
 end;
 
 constructor TStockDayLineKDataReader.Create (AQuery: TADOQuery; ALocation: string;
   RSSDest: string);
 begin
   FStockIDList := TStringList.Create;
   FQuery := AQuery;
   SetLocation (ALocation);
   FRSSLocation := RSSDest;
 end;
 
 destructor TStockDayLineKDataReader.Destroy;
 begin
   Clear;
   
   if Assigned (FStockIDList) then
     FreeAndNil (FStockIDList);
      
   inherited;
 end;
 
 // Description: Retrieves the identifiers of speicified stocks.
 // Parameters:
 //    [out] ABuffer: specifies a buffer to receive the identifiers of stocks.
 //    [in] DataPath: specifies the path string with wildcard mask.
 // Return Value: None.
 // Remark: None.
 procedure TStockDayLineKDataReader.GetStockIDFiles(ABuffer: TStrings; DataPath: string);
 var
   sr: TSearchRec;
   FileAttrs: Integer;
 begin
   if (not Assigned (ABuffer)) or (Trim (DataPath) = '') then Exit;
   ABuffer.Clear;
 
   FileAttrs := faAnyFile;
   if FindFirst (DataPath, FileAttrs, sr) = 0 then
   begin
     repeat
       ABuffer.Add (sr.Name);
     until FindNext (sr) <> 0;
     FindClose (sr);
   end; // end if
 end;
 
 function TStockDayLineKDataReader.GetStockMarketInfo: string;
 var
   ix: Integer;
   Obj: TDayLineKProperty;
   Val: string;
 
   function GetOpen: string;
   begin
     Result := Format ('开=<b>%f</b>', [Obj.Open/1000]);
   end;
 
   function GetClose: string;
   begin
     Result := Format ('收=<b>%f</b>', [Obj.Close/1000]);
   end;
 
   function GetHigh: string;
   begin
     Result := Format ('高=<b>%f</b>', [Obj.High/1000]);
   end;
 
   function GetLow: string;
   begin
     Result := Format ('低=<b>%f</b>', [Obj.Low/1000]);
   end;
 
   function GetQuantity: string;
   begin
     Result := Format ('成交量=%d', [Obj.TranQuantity]);
   end;
 
   function GetSum: string;
   begin
     Result := Format ('交易额=%d', [Obj.Sum]);
   end;
 
 begin
   for ix := 0 to Pred (FStockList.Count) do
   begin
     Obj := (FStockList.Items[ix] as TDayLineKProperty);
     Val := Format ('<b>%s</b>: %s %s %s %s %s %s'#13#13,
       [Obj.ID, GetClose, GetOpen, GetHigh, GetLow, GetSum, GetQuantity]);
     if ix mod 2 = 0 then
       Val := Format ('<font style="background-color:#99CCFF">%s</font>', [Val]);
     Result := Format ('%s%s', [Result, Val]);
   end;
 end;
 
 procedure TStockDayLineKDataReader.Load;
 var
   ix: Integer;
 begin
   Clear;
   FStockList := TObjectList.Create;
 
   GetStockIDFiles (FStockIDList,
     Format ('%s/6*.day', [ExcludeTrailingPathDelimiter (FSHDayLocation)]));
   for ix := 0 to Pred (FStockIDList.Count) do
     ReadData (Format ('%s/%s', [ExcludeTrailingPathDelimiter (FSHDayLocation),
       FStockIDList[ix]]));
 
   GetStockIDFiles (FStockIDList,
     Format ('%s/0*.day', [ExcludeTrailingPathDelimiter (FSZDayLocation)]));
   for ix := 0 to Pred (FStockIDList.Count) do
     ReadData (Format ('%s/%s', [ExcludeTrailingPathDelimiter (FSZDayLocation),
       FStockIDList[ix]]));
 end;
 
 procedure TStockDayLineKDataReader.ReadData(AFileName: string);
 const
   CSRecordBytes: Integer = 40;
 var
   DataFile: File;
   Days: Integer;
   DateVal,
   OpenVal,
   CloseVal,
   HighVal,
   LowVal,
   SumVal,
   TranQuantityVal: DWORD;
 begin
   AssignFile (DataFile, AFileName);
   try
     Reset (DataFile, 1);
     Days := Round (FileSize (DataFile) / CSRecordBytes);
     // to locate to the latest day
     Seek (DataFile, Pred (Days) * CSRecordBytes);
 
     BlockRead (DataFile, DateVal, SizeOf (DateVal));
     BlockRead (DataFile, OpenVal, SizeOf (OpenVal));
     BlockRead (DataFile, HighVal, SizeOf (HighVal));
     BlockRead (DataFile, LowVal, SizeOf (LowVal));
     BlockRead (DataFile, CloseVal, SizeOf (CloseVal));
     BlockRead (DataFile, SumVal, SizeOf (SumVal));
     BlockRead (DataFile, TranQuantityVal, SizeOf (TranQuantityVal));
     // skip the three reserved items left...
 
     FStockList.Add (TDayLineKProperty.Create (
       LeftStr (ExtractFileName (AFileName), 6),
       DateVal, OpenVal, CloseVal, HighVal,
       LowVal, TranQuantityVal, SumVal));
   finally
     CloseFile (DataFile);
   end; // end try_finally
 end;
 
 procedure TStockDayLineKDataReader.SaveToDatabase;
 var
   ix: Integer;
 begin
   ClearDayLineKData;
   for ix := 0 to Pred (FStockList.Count) do
     WriteToDB (FStockList.Items[ix] as TDayLineKProperty);
 end;
 
 procedure TStockDayLineKDataReader.SaveToRSS;
 var
   RSSNode, ChannelNode,
   ItemNode, Node: IXMLNode;
   xml: TXMLDocument;
 begin
   if Trim (FRSSLocation) = '' then Exit;
   xml := TXMLDocument.Create (nil);
   try                     
     xml.Active := True;
     xml.FileName := ExcludeTrailingPathDelimiter (FRSSLocation) + '/StockRSS.xml';
     xml.Version := '1.0';
 
     RSSNode := xml.CreateNode ('rss');
     xml.DocumentElement := RSSNode;
     RSSNode.AttributeNodes.Add (xml.CreateNode ('version', ntAttribute));
     RSSNode.Attributes['version'] := 2;
 
     ChannelNode := xml.CreateNode ('channel');
     RSSNode.ChildNodes.Add (ChannelNode);
 
     Node := xml.CreateNode ('title');
     Node.ChildNodes.Add (xml.CreateNode ('Stock Market', ntText));
     ChannelNode.ChildNodes.Add (Node);
 
     Node := xml.CreateNode ('link');
     Node.ChildNodes.Add (xml.CreateNode ('http://blog.csdn.net/wangchinaking', ntText));
     ChannelNode.ChildNodes.Add (Node);
 
     Node := xml.CreateNode ('description');
     Node.ChildNodes.Add (xml.CreateNode ('', ntText));
     ChannelNode.ChildNodes.Add (Node);
    
     Node := xml.CreateNode ('language');
     Node.ChildNodes.Add (xml.CreateNode ('en-us', ntText));
     ChannelNode.ChildNodes.Add (Node);
 
     Node := xml.CreateNode ('pubDate');
     Node.ChildNodes.Add (xml.CreateNode (DateTimeToStr (Now), ntText));
     ChannelNode.ChildNodes.Add (Node);
 
     Node := xml.CreateNode ('lastBuildDate');
     Node.ChildNodes.Add (xml.CreateNode (DateTimeToStr (Now), ntText));
     ChannelNode.ChildNodes.Add (Node);
 
     Node := xml.CreateNode ('docs');
     Node.ChildNodes.Add (xml.CreateNode ('http://blogs.law.harvard.edu/tech/rss', ntText));
     ChannelNode.ChildNodes.Add (Node);
 
     Node := xml.CreateNode ('generator');
     Node.ChildNodes.Add (xml.CreateNode ('StockRSS Generator', ntText));
     ChannelNode.ChildNodes.Add (Node);
 
     Node := xml.CreateNode ('managingEditor');
     Node.ChildNodes.Add (xml.CreateNode (
'wangchi_cn@21cn.com', ntText));
     ChannelNode.ChildNodes.Add (Node);
 
     Node := xml.CreateNode ('webMaster');
     Node.ChildNodes.Add (xml.CreateNode (
'wangchi_cn@21cn.com', ntText));
     ChannelNode.ChildNodes.Add (Node);
 
     ItemNode := xml.CreateNode ('item');   
     ChannelNode.ChildNodes.Add (ItemNode);
 
     Node := xml.CreateNode ('title');
     Node.ChildNodes.Add (xml.CreateNode ('当日行情', ntText));
     ItemNode.ChildNodes.Add (Node);
    
     Node := xml.CreateNode ('link');
     Node.ChildNodes.Add (xml.CreateNode ('', ntText));
     ItemNode.ChildNodes.Add (Node);
 
     Node := xml.CreateNode ('description');
     Node.ChildNodes.Add (xml.CreateNode (GetStockMarketInfo, ntText));
     ItemNode.ChildNodes.Add (Node);
 
     Node := xml.CreateNode ('pubDate');
     Node.ChildNodes.Add (xml.CreateNode (DateTimeToStr (Now), ntText));
     ItemNode.ChildNodes.Add (Node);
 
     Node := xml.CreateNode ('guid');
     Node.ChildNodes.Add (xml.CreateNode ('', ntText));
     ItemNode.ChildNodes.Add (Node);
 
     ///
     xml.SaveToFile;
     xml.Active := False;
   finally
     FreeAndNil (xml);
   end;
 end;
 
 procedure TStockDayLineKDataReader.SetLocation(AValue: string);
 begin
   FLocation := ExcludeTrailingPathDelimiter (AValue);
   if Trim (FLocation) = '' then
   begin
     FSHDayLocation := '';
     FSZDayLocation := '';
     Exit;
   end;
 
   FSHDayLocation := Format ('%s/DATA/SHase/Day', [FLocation]);
   FSZDayLocation := Format ('%s/DATA/SZnse/Day', [FLocation]);
 end;
 
 procedure TStockDayLineKDataReader.WriteToDB (DayLineObj: TDayLineKProperty);
 begin
   if (not Assigned (FQuery)) or (not Assigned (DayLineObj)) then Exit;
 
   with FQuery do
   begin
     Close;
     SQL.Clear;
     SQL.Add ('INSERT INTO db_DayLineK');
     SQL.Add ('(Dlk_StockID, Dlk_Date, Dlk_Open, Dlk_High,');
     SQL.Add (' Dlk_Close, Dlk_Low, Dlk_TranQuantity, Dlk_Sum)');
     SQL.Add ('VALUES (:ID, :Date, :Open, :High, :Close, :Low, :Quan, :Sum)');
     with Parameters do
     begin
       with ParamByName ('ID') do
       begin
         DataType := ftString;
         Value := DayLineObj.ID;
       end;
       with ParamByName ('Date') do
       begin
         DataType := ftInteger;
         Value := DayLineObj.Date;
       end;
       with ParamByName ('Open') do
       begin
         DataType := ftInteger;
         Value := DayLineObj.Open;
       end;
       with ParamByName ('High') do
       begin
         DataType := ftInteger;
         Value := DayLineObj.High;
       end;
       with ParamByName ('Close') do
       begin
         DataType := ftInteger;
         Value := DayLineObj.Close;
       end;
       with ParamByName ('Low') do
       begin
         DataType := ftInteger;
         Value := DayLineObj.Low;
       end;
       with ParamByName ('Quan') do
       begin
         DataType := ftLargeint;
         Value := DayLineObj.TranQuantity;
       end;
       with ParamByName ('Sum') do
       begin
         DataType := ftLargeint;
         Value := Round (DayLineObj.Sum/10);
       end;                     
     end; // end with
     Prepared := True;
     try
       try
         ExecSQL;
       except
         // nothing to do
       end; //end try_except
     finally
       Close;
     end; //end try_finally
   end; //end with_do
 end;
 
 procedure TStockRSSSvc.ServiceStart(Sender: TService;
   var Started: Boolean);
 var
   inifile: TIniFile;
 begin
   CoInitialize (nil);
   STRConn.Close;
   STRConn.ConnectionString := Format ('Provider=%s;Data Source=%s%s;'+
       'Persist Security Info=False;Jet OLEDB:Database Password=1428wc',
       ['Microsoft.Jet.OLEDB.4.0', GetWorkingPath, 'StockDB.mdb']);
   try
     STRConn.Open;
   except
     raise Exception.Create ('Failed to make a connection with local stock database!');
   end;
 
   inifile := TIniFile.Create (Format ('%s%s', [GetWorkingPath, 'main.ini']));
   try
     Timer1.Interval := 1000 * inifile.ReadInteger ('general', 'AutoRefresh', 13);
     FLineKReader := TStockDayLineKDataReader.Create (
       qryCommon,
       inifile.ReadString ('general', 'DZHLocation', ''),
       inifile.ReadString ('general', 'RSSLocation', ''));
   finally
     FreeAndNil (inifile);
   end;
 
   Timer1.Enabled := True;
   Started := True;
 end;
 
 procedure TStockRSSSvc.ServiceStop(Sender: TService; var Stopped: Boolean);
 begin
   Timer1.Enabled := False;
   if Assigned (FLineKReader) then
     FreeAndNil (FLineKReader);
   STRConn.Close;
   Stopped := True;
 end;
 
 procedure TStockRSSSvc.Timer1Timer(Sender: TObject);
 begin
   if not Assigned (FLineKReader) then Exit;
   Timer1.Enabled := False;
   try
     FLineKReader.Load;
     FLineKReader.SaveToRSS;
   //  FLineKReader.SaveToDatabase;
   finally
     Timer1.Enabled := True;
   end;
 end;
 
 end.
                   

 
 
 
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值