以下是如何生成当今比较流行的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.
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.