大家都知道TClientDataSet的Delta屬性保存數據集的變化,但是Delta是OleVariant類型的屬性,這樣如果用Delphi寫Webservice,就有需要把它轉成XML,特別是其他語言也要用這個Webservice的時候,因爲如果Delta能和XML相互轉換,Delta包的結構就是透明的了。而TClientDataSet卻沒有提供DeltaXML這樣的屬性,之前在網上找了一下,發現網上的都是把Delta賦給另一個TClientDataSet的Data,然後再通過XMLData返回XML,但這樣爲了一個簡單的功能就得多創建一個對象實例,感覺很不好,於是研究一下TClientDataSet的源碼,終於完成了Delta與XML相互轉換的函數,代碼如下:
unit uDelta;
interface
uses DBClient,DSIntf,VarUtils,ActiveX;
function DeltaToXML(Delta:OleVariant):String;
function XMLToDelta(XMLData:String):OleVariant;
implementation
procedure Check(FDSBase:IDSBase;Status: DBResult);
var
ErrMsg: array[0..2048] of Char;
begin
if Status <> 0 then
begin
FDSBase.GetErrorString(Status, ErrMsg);
raise EDBClient.Create(ErrMsg, Status);
end;
end;
function DeltaToXML(Delta:OleVariant):String;
var
FDSBase: IDSBase;
DataPacket: TDataPacket;
VarPacket: OleVariant;
begin
CreateDbClientObject(CLSID_DSBase, IDSBase, FDSBase);
SafeArrayCheck(ActiveX.SafeArrayCopy(VarToDataPacket(Delta), DataPacket));
Check(FDSBase,FDSBase.AppendData(DataPacket, True));
FDSBase.SetProp(dspropXML_STREAMMODE, xmlON);
Check(FDSBase,FDSBase.StreamDS(DataPacket));
DataPacketToVariant(DataPacket, VarPacket);
Result := VariantArrayToString(VarPacket);
//FreeDataPacket(DataPacket);
end;
function XMLToDelta(XMLData:String):OleVariant;
var Delta:OleVariant;
DataPacket: TDataPacket;
FDSBase: IDSBase;
begin
Delta:=StringToVariantArray(XMLData);
SafeArrayCheck(SafeArrayCopy(VarToDataPacket(Delta), DataPacket));
CreateDbClientObject(CLSID_DSBase, IDSBase, FDSBase);
Check(FDSBase,FDSBase.AppendData(DataPacket, True));
FDSBase.SetProp(dspropXML_STREAMMODE, xmlOFF);
Check(FDSBase,FDSBase.StreamDS(DataPacket));
DataPacketToVariant(DataPacket, Result);
//FreeDataPacket(DataPacket);
end;
end.