延迟方法-如何用itunes备份

quotedstr
2023年4月3日发(作者:typecho)

燃气公司呼叫中心系统概要设计

functionStringReplace(constS,OldPattern,NewPattern:string;

Flags:TReplaceFlags):string;

var

SearchStr,Patt,NewStr:string;

Offset:Integer;

begin

ifrfIgnoreCaseinFlagsthen

begin

SearchStr:=UpperCase(S);

Patt:=UpperCase(OldPattern);

endelse

begin

SearchStr:=S;

Patt:=OldPattern;

end;

NewStr:=S;

Result:='';

whileSearchStr<>''do

begin

Offset:=Pos(Patt,SearchStr);

ifOffset=0then

begin

Result:=Result+NewStr;

Break;

end;

Result:=Result+Copy(NewStr,1,Offset-1)+NewPattern;

NewStr:=Copy(NewStr,Offset+Length(OldPattern),MaxInt);

ifnot(rfReplaceAllinFlags)then

begin

Result:=Result+NewStr;

Break;

end;

SearchStr:=Copy(SearchStr,Offset+Length(Patt),MaxInt);

end;

end;

functionStrToInt64Def(constAValue:string;ADefault:int64):int64;

begin

Result:=StrToIntDef(AValue,ADefault);

end;

functionStrToInt64(constAValue:string):int64;

begin

Result:=StrToInt(AValue);

end;

{$ENDIF}

//Delphi4stubs

{$IFNDEFD5UP}

functionAnsiPos(constSubstr,S:string):Integer;

begin

Result:=Pos(Substr,S);

end;

functionAnsiQuotedStr(constS:string;Quote:Char):string;

var

P,Src,Dest:PChar;

AddCount:Integer;

begin

AddCount:=0;

P:=StrScan(PChar(S),Quote);

whileP<>nildo

begin

Inc(P);

Inc(AddCount);

P:=StrScan(P,Quote);

end;

ifAddCount=0then

begin

Result:=Quote+S+Quote;

Exit;

end;

SetLength(Result,Length(S)+AddCount+2);

Dest:=Pointer(Result);

Dest^:=Quote;

Inc(Dest);

Src:=Pointer(S);

P:=StrScan(Src,Quote);

repeat

Inc(P);

Move(Src^,Dest^,P-Src);

Inc(Dest,P-Src);

Dest^:=Quote;

Inc(Dest);

Src:=P;

P:=StrScan(Src,Quote);

untilP=nil;

P:=StrEnd(Src);

Move(Src^,Dest^,P-Src);

Inc(Dest,P-Src);

Dest^:=Quote;

end;

functionAnsiExtractQuotedStr(varSrc:PChar;Quote:Char):string;

var

P,Dest:PChar;

DropCount:Integer;

begin

Result:='';

if(Src=nil)or(Src^<>Quote)then

Exit;

Inc(Src);

DropCount:=1;

P:=Src;

Src:=StrScan(Src,Quote);

whileSrc<>nildo

begin

Inc(Src);

ifSrc^<>Quotethen

Break;

Inc(Src);

Inc(DropCount);

Src:=StrScan(Src,Quote);

end;

ifSrc=nilthen

Src:=StrEnd(P);

if((Src-P)<=1)then

Exit;

ifDropCount=1then

SetString(Result,P,Src-P-1)

else

begin

SetLength(Result,Src-P-DropCount);

Dest:=PChar(Result);

Src:=StrScan(P,Quote);

whileSrc<>nildo

begin

Inc(Src);

ifSrc^<>Quotethen

Break;

Move(P^,Dest^,Src-P);

Inc(Dest,Src-P);

Inc(Src);

P:=Src;

Src:=StrScan(Src,Quote);

end;

ifSrc=nilthen

Src:=StrEnd(P);

Move(P^,Dest^,Src-P-1);

end;

end;

procedureFreeAndNil(varObj);

var

P:TObject;

begin

P:=TObject(Obj);

TObject(Obj):=nil;

;

end;

{$ENDIF}

//.

functionStreamWrite(Stream:TStream;constBuffer{$IFDEFCLR}:TBytes{$ENDIF};Offset,Count:

Longint):Longint;

begin

{$IFDEFCLR}

Result:=(Buffer,Offset,Count);

{$ELSE}

Result:=(TBytes(Buffer)[Offset],Count);

{$ENDIF}

end;

{$IFNDEFCLR}

//Delphi'simplementationofTStringStreamisseverelyflawed,itdoesaSetLength

//oneachwrite,plementationover-

//comesthisissue.

type

TsdStringStream=class(TMemoryStream)

public

constructorCreate(constS:string);

functionDataString:string;

end;

深圳市博域信源通讯有限公司一体化呼叫中心平台产品BYICC2.0典型成功案例汇总

住房公积金管理中心行业

内蒙古自治区乌兰察布市住房公积金管理中心12329住房公积金热线呼叫中心系统

自来水/供水行业

广东省佛山市水业集团有限公司客户服务中心(CallCenter/呼叫中心)系统

贵州省安顺市供水总公司呼叫中心系统

佛山水业三水供水有限公司呼叫中心(CallCenter)系统

深圳市布吉供水有限公司呼叫中心(CallCenter)系统

湖北省恩施市自来水有限责任公司96510供水服务热线呼叫中心系统

公安机关

山东省招远市公安局指挥中心110/119/122三台合一接处警系统

湖南省永州市新田县公安局指挥中心110/119/122三台合一接处警系统

西藏昌都地区江达县公安局指挥中心110/119/122三台合一接处警系统

湖南省岳阳市公安局交通警察支队122接警处警系统

山东省菏泽市公安局110自动语音回访系统

黑龙江省牡丹江市柴河林业局综合指挥中心110/119/122三台合一接处警系统

电力行业

江西省吉安市遂川县95598电力客户服务中心系统

内蒙古兴安盟乌兰浩特市电业局95598电力客户服务中心系统

内蒙托克托县电业局95598电力客户服务中心系统

江西省赣州市安远县/崇义县/大余县/定南县/赣县/会昌县/信丰县电业局95598电力客

户服务中心系统

广西壮族自治区河池市环江县电业总公司95598电力客户服务中心系统

包头市达茂(旗)电力有限责任公司95598电力客户服务中心系统

黑龙江省尚志市电力公司95598电力客户服务中心系统

燃气/热电/供暖行业

南宁市海方燃气有限责任公司客户服务中心(CallCenter)系统

威海第二热电集团有限公司客户服务热线呼叫中心&CRM一体化系统

南宁市金焰燃气有限责任公司客户服务中心(CallCenter/呼叫中心)系统

佛山市顺德兴顺燃气有限公司客户服务热线呼叫中心系统

南宁华侨投资区侨联燃气有限责任公司客户服务热线呼叫中心&CRM一体化系统

紧急救援/居家养老服务/智慧养老服务行业

重庆市九龙坡区民政局居家养老服务呼叫中心系统平台

福建省莆田市老龄工作委员会居家养老服务呼叫中心系统平台

泉州市民政局(泉州市老龄办)的泉州市居家养老服务信息呼叫中心平台

广州志朗电脑技术有限公司平安钟服务平台呼叫中心系统

北京万家安全系统有限公司居家养老信息服务系统

东莞市永华智能系统有限公司汽车GPS防盗防劫监控中心(110CAS报警中心)客户服务

热线系统

北京家健产业有限公司居家养老服务系统

顺德华峰实业有限公司110网络监控中心呼叫中心系统

劳动和社会保障行业

湖北省钟祥市劳动和社会保障局12333劳动和社会保障电话服务中心系统

广东省茂名市劳动和社会保障局12333劳动和社会保障电话咨询服务热线系统

广东省阳江市劳动和社会保障局12333劳动和社会保障电话咨询服务热线系统

广东省清远市劳动和社会保障局12333劳动和社会保障电话服务中心系统

交通运输/物流/汽车制造/地铁/城市轨道交通行业

东莞文一.红叶集团呼叫中心系统

香港昌机集团有限公司物流呼叫中心与车辆调度系统

宁夏北方飞扬贸易有限公司物流信息呼叫中心(CallCenter)系统

港铁轨道交通(深圳)有限公司/深圳地铁四号线客户服务热线呼叫中心系统

港铁轨道交通(深圳)有限公司/深圳地铁四号线客户服务热线呼叫中心系统的应急备

用系统

港铁轨道交通(深圳)有限公司/深圳地铁四号线客户服务热线呼叫中心系统UAT测试

重庆长安铃木汽车有限公司客户服务中心系统

重庆长安铃木汽车有限公司客户服务热线呼叫中心容灾系统

广电网络/数字电视/传媒行业

大连广播电视台新闻热线呼叫中心系统

云南广电网络集团有限公司大理分公司客户服务中心(呼叫中心)系统

云南省丽江市有线电视网络有限公司客户服务中心(呼叫中心)系统

云南广电网络集团有限公司昭通分公司客户服务中心(呼叫中心)系统

云南广电网络集团有限公司文山分公司客户服务中心(呼叫中心)系统

云南广电网络集团有限公司保山分公司客户服务中心(呼叫中心)系统

云南广电网络集团有限公司西双版纳分公司客户服务中心(呼叫中心)系统

旅游/旅行社/酒店行业

深圳枫叶酒店呼叫中心(电话订房)系统

深圳市世纪风行旅行社有限公司呼叫中心(CallCenter)系统

中青旅山水酒店投资管理有限公司呼叫中心(电话订房)系统

广州白天鹅宾馆(中国第一家中外合作的五星级宾馆)呼叫中心系统

广州市心友汇文化传播有限公司呼叫中心(CallCenter)系统

房地产行业

重庆港源房地产开发有限公司呼叫中心系统

深圳房地产信息网(/)呼叫中心系统

电话营销/电子商务/外包服务(BPO)行业

贵州四方鼎立咨询服务有限公司为贵州移动提供配套增值业务服务的外包呼叫中心系

统(含电话营销外呼系统)

广州剑奇贸易公司医疗保健电视购物呼叫中心系统

深圳市炫捷网络科技有限公司保险电话营销外包呼叫中心系统

无锡市美洋洋生活在线电话营销呼叫中心系统

深圳华强集团有限公司华强电子世界网客户服务中心系统

金融/保险行业

天安保险股份有限公司浙江分公司客户服务热线系统

深圳市信乐保险代理有限公司客户服务中心(CallCenter)系统

中国银行股份有限公司惠州分行(包括总部以及各个营业网点)电话录音系统

电信通信/运营商行业

新疆特力电信实业有限责任公司客户服务中心系统

中国网通(集团)有限公司天津市分公司"信息家园"内容认购综合认证平台

广州珠江电信设备制造有限公司客户服务中心(CallCenter)系统

城市管理/数字化城市行业

山东省淄博市淄川区城市管理行政执法局数字化城市监督指挥中心12319城管服务热

线呼叫中心系统

环境保护/环保局行业

贵州省毕节市环境监察支队(贵州省毕节市环境保护局)12369环保举报热线呼叫中心系

河南省新乡市12369环保投诉热线系统

宁夏回族自治区银川市环保局12369投诉热线系统

深圳市宝安区环保局客户服务中心(CallCenter)系统

江苏省无锡市环保局12369环保热线服务系统

上海市宝山区环保监测监控系统/12369环保热线服务系统

医院/医疗器械/医疗卫生行业

昆明市寻甸回族彝族自治县第一人民医院电话预约挂号呼叫中心系统

长沙三诺生物传感技术股份有限公司客户服务中心(CallCenter)系统

上海市杨浦区中心医院客户服务中心系统

大理市第二人民医院电话预约挂号呼叫中心系统

商务局

内蒙古自治区巴彦淖尔市商务局12312商务举报投诉服务热线系统(呼叫中心系统)

出入境检验检疫局/质量技术监督局

广西出入境检验检疫局12365举报处置指挥系统平台(呼叫中心系统)

海关

广东省江门海关统一服务热线系统

司法局

深圳市司法局电话语音声纹识别呼叫中心系统

福建省泉州市司法局12348法律服务热线系统

(constS:string);

begin

inheritedCreate;

SetSize(length(S));

ifSize>0then

begin

Write(S[1],Size);

Position:=0;

end;

end;

ring:string;

begin

SetLength(Result,Size);

ifSize>0then

begin

Position:=0;

Read(Result[1],length(Result));

end;

end;

{$ELSE}

//sethestandardTStringStream

type

TsdStringStream=TStringStream;

{$ENDIF}

//Utilityfunctions

functionMin(A,B:integer):integer;

begin

ifA

Result:=A

else

Result:=B;

end;

functionMax(A,B:integer):integer;

begin

ifA>Bthen

Result:=A

else

Result:=B;

end;

functionEscapeString(constAValue:string):string;

var

i:integer;

begin

Result:=AValue;

fori:=0tocEscapeCount-1do

Result:=StringReplace(Result,cEscapes[i],cReplaces[i],[rfReplaceAll]);

end;

functionUnEscapeStringUTF8(constAValue:string):string;

var

SearchStr,Reference,Replace:string;

i,Offset,Code:Integer;

W:word;

begin

SearchStr:=AValue;

Result:='';

whileSearchStr<>''do

begin

//find'&'

Offset:=AnsiPos('&',SearchStr);

ifOffset=0then

begin

//Nothingfound

Result:=Result+SearchStr;

Break;

end;

Result:=Result+Copy(SearchStr,1,Offset-1);

SearchStr:=Copy(SearchStr,Offset,MaxInt);

//findnext';'

Offset:=AnsiPos(';',SearchStr);

ifOffset=0then

begin

//Error:encountereda'&'butnota';'..wewillignore,justreturn

//theunmodifiedvalue

Result:=Result+SearchStr;

Break;

end;

//Reference

Reference:=copy(SearchStr,1,Offset);

SearchStr:=Copy(SearchStr,Offset+1,MaxInt);

Replace:=Reference;

//Seeifitisacharacterreference

ifcopy(Reference,1,2)='&#'then

begin

Reference:=copy(Reference,3,length(Reference)-3);

iflength(Reference)>0then

begin

iflowercase(Reference[1])='x'then

//Hexnotation

Reference[1]:='$';

Code:=StrToIntDef(Reference,-1);

if(Code>=0)and(Code<$FFFF)then

begin

W:=Code;

{$IFDEFD5UP}

Replace:=sdUnicodeToUtf8(WideChar(W));

{$ELSE}

Replace:=char(Wand$FF);

{$ENDIF}

end;

end;

endelse

begin

//Lookupdefaultescapes

fori:=0tocEscapeCount-1do

ifReference=cReplaces[i]then

begin

//Replace

Replace:=cEscapes[i];

Break;

end;

end;

//Newresult

Result:=Result+Replace;

end;

end;

functionUnEscapeStringANSI(constAValue:string):string;

var

SearchStr,Reference,Replace:string;

i,Offset,Code:Integer;

B:byte;

begin

SearchStr:=AValue;

Result:='';

whileSearchStr<>''do

begin

//find'&'

Offset:=AnsiPos('&',SearchStr);

ifOffset=0then

begin

//Nothingfound

Result:=Result+SearchStr;

Break;

end;

Result:=Result+Copy(SearchStr,1,Offset-1);

SearchStr:=Copy(SearchStr,Offset,MaxInt);

//findnext';'

Offset:=AnsiPos(';',SearchStr);

ifOffset=0then

begin

//Error:encountereda'&'butnota';'..wewillignore,justreturn

//theunmodifiedvalue

Result:=Result+SearchStr;

Break;

end;

//Reference

Reference:=copy(SearchStr,1,Offset);

SearchStr:=Copy(SearchStr,Offset+1,MaxInt);

Replace:=Reference;

//Seeifitisacharacterreference

ifcopy(Reference,1,2)='&#'then

begin

Reference:=copy(Reference,3,length(Reference)-3);

iflength(Reference)>0then

begin

iflowercase(Reference[1])='x'then

//Hexnotation

Reference[1]:='$';

Code:=StrToIntDef(Reference,-1);

if(Code>=0)and(Code<$FF)then

begin

B:=Code;

Replace:=char(B);

end;

end;

endelse

begin

//Lookupdefaultescapes

fori:=0tocEscapeCount-1do

ifReference=cReplaces[i]then

begin

//Replace

Replace:=cEscapes[i];

Break;

end;

end;

//Newresult

Result:=Result+Replace;

end;

end;

functionQuoteString(constAValue:string):string;

var

AQuoteChar:char;

begin

AQuoteChar:='"';

ifPos('"',AValue)>0then

AQuoteChar:='''';

{$IFDEFCLR}

Result:=QuotedStr(AValue,AQuoteChar);

{$ELSE}

Result:=AnsiQuotedStr(AValue,AQuoteChar);

{$ENDIF}

end;

functionUnQuoteString(constAValue:string):string;

{$IFNDEFCLR}

var

P:PChar;

{$ENDIF}

begin

ifLength(AValue)<2then

begin

Result:=AValue;

exit;

end;

ifAValue[1]incQuoteCharsthen

begin

{$IFDEFCLR}

Result:=DequotedStr(AValue,AValue[1]);

{$ELSE}

P:=PChar(AValue);

Result:=AnsiExtractQuotedStr(P,AValue[1]);

{$ENDIF}

endelse

Result:=AValue;

end;

functionAddControlChars(constAValue:string;constChars:string;Interval:integer):string;

//InsertCharsinAValueateachIntervalchars

var

i,j,ALength:integer;

//local

procedureInsertControlChars;

var

k:integer;

begin

fork:=1toLength(Chars)do

begin

Result[j]:=Chars[k];

inc(j);

end;

end;

//main

begin

if(Length(Chars)=0)or(Interval<=0)then

begin

Result:=AValue;

exit;

end;

//Calculatelengthbasedonoriginallengthandtotalextralengthforcontrolchars

ALength:=Length(AValue)+((Length(AValue)-1)divInterval+3)*Length(Chars);

SetLength(Result,ALength);

//Copyandinsert

j:=1;

fori:=1toLength(AValue)do

begin

if(imodInterval)=1then

//Insertcontrolchars

InsertControlChars;

Result[j]:=AValue[i];

inc(j);

end;

InsertControlChars;

//Adjustlength

dec(j);

ifALength>jthen

SetLength(Result,j);

end;

functionRemoveControlChars(constAValue:string):string;

//RemovecontrolcharactersfromstringinAValue

var

i,j:integer;

begin

Setlength(Result,Length(AValue));

i:=1;

j:=1;

whilei<=Length(AValue)do

ifAValue[i]incControlCharsthen

inc(i)

else

begin

Result[j]:=AValue[i];

inc(i);

inc(j);

end;

//Adjustlength

ifi<>jthen

SetLength(Result,j-1);

end;

functionFindString(constSubString:string;constS:string;Start,Close:integer;varAPos:integer):

boolean;

//CheckiftheSubstringmatchesthestringSinanypositioninintervalStarttoClose-1

//=Trueifanythingisfound.

//Note:thisfuntioniscase-insensitive

var

CharIndex:integer;

begin

Result:=False;

APos:=0;

forCharIndex:=StarttoClose-Length(SubString)do

ifMatchString(SubString,S,CharIndex)then

begin

APos:=CharIndex;

Result:=True;

exit;

end;

end;

functionMatchString(constSubString:string;constS:string;Start:integer):boolean;

//CheckiftheSubstringmatchesthestringSatpositionStart.

//Note:thisfuntioniscase-insensitive

var

CharIndex:integer;

begin

Result:=False;

//Checkrangejustincase

if(Length(S)-Start+1)

exit;

CharIndex:=0;

whileCharIndex

ifUpcase(SubString[CharIndex+1])=Upcase(S[Start+CharIndex])then

inc(CharIndex)

else

exit;

//Allcharswerethesame,sowesucceeded

Result:=True;

end;

随着经济的发展和社会信息化程度的提高,人们的生活质量和工作效率也越来越高,消费者

对企业的服务质量也提出了越来越高的要求。企业为了争夺客户资源

,必须能够准确把握住消费者的需求,并以最快的速度做出响应。

燃气公司面向市民经营燃气等特殊商品,有其固有的特点。由于面向庞大的用户群,燃气又

是关系千家万户生活的必需品,每一位用户的电话我们都必须作出快

速的响应,满足用户的需求。

同时,由于经营的商品危险性比较高,对安全供气和用户的安全用气的要求是及其严格的。

目前,燃气公司通常已经开通的热线有主要有业务热线、抢修热线和

送气预约热线,但这些热线往往不能覆盖并统筹管理整个服务层面,因此,无论是用户向燃

气公司索取服务,或燃气公司向用户提供服务,仍然存在许多不便,

服务响应速度和服务质量也无法得到有效的控制,不仅增加了服务成本,还制约了燃气供应

业务在本地区取得最大规模的发展。

此外,由于传统热线没有将客户数据、业务数据和业务流程整合起来,许多有价值的记录,

许多重复出现的问题,都淹没在日常工作中,对燃气公司进一步提升

运营管理水平,挖掘业务潜力,提高企业效益都极为不利。这将带来以下问题难以解决:

(1)电话是最原始的沟通手段,而且电话有它不可弥补的缺陷。电话只是1对1的服务,

如果有第2个人打电话进来只能听见占线的声音。如果访问量很大的话,

没有多少人能真正得到专业的指导。呼叫中心能够从根本上解决上述问题,而且系统运行正

常。

(2)客户欠款的催缴完全要通过人工拨号来实现,工作量很大。

(3)公司在下班时间后,难以为客户提供服务,难以做到全天候24小时的优质服务。

(4)难以事先了解客户信息、服务历史记录等相关信息,以便为其提供更有针对性的个性

化服务。

(5)难以针对客户的具体情况安排有特殊技能的话务员以满足客户的要求,对话务员的专

业水平要求较高。

(6)难以使客户得到"直通车"式的服务,客户可能拨打了多个电话,问题也得不到解决。

也就是难以实现"只要您一个电话,剩下的事情由我来做"。

(7)难以实现完善的客户信息管理、客户分析、业务分析等功能,为公司领导决策提供事

实依据。

随着公众电话的普及,越来越多的业务通过电话、传真的方式达成。有大量的燃气公司方面

基本法规等业务咨询电话、燃气公司费催缴电话、燃气抢修电话、投

诉电话、用户基本价查询/计费查询电话等,用户通过电话达成的业务已经占到燃气公司业

务的相当比例。由于各种业务电话分散,给客户带来诸多不便,同时,

燃气公司内部各部门也难以及时有效沟通,无法对外提供统一口径的服务。

同时随着外来燃气企业的不断涌现,燃气市场的竞争在不断加剧。同时,市场竞争的加剧和

生活条件的改善使得客户对服务质量的要求不断提高,以往的服务质

量已远远不能满足广大客户的需求。在这种情况下,只有以更完善、更高效、更优质的服务

来提高客户的满意度,增强自身的竞争能力。另一方面,对于企业的

内部管理来说,一成不变的管理模式不但不能满足日益扩展的业务需要,而且会在一定程度

上阻碍企业的发展。如何为客户提供"一个电话对外"和"一站式"的服

务便成了燃气公司最急待解决的课题。

随着近年来CTI技术和呼叫中心技术的蓬勃发展,使这一问题迎刃而解。我们能够方便地建

设一套技术先进、稳定高效、价格合理、适合于燃气公司的呼叫中心。

呼叫中心(CallCenter)是指以电话接入为主的呼叫响应中心,它为用户提供各种电话响应服

务。以CTI(计算机电话语音集成技术ComputerTelephony

Integration)技术为核心的呼叫中心是一个集语音技术、呼叫处理、计算机网络和数据库技

术于一体的系统。新一代的呼叫中心将计算机网络和通信网紧密结合

起来,这有利于把呼叫中心的技术平台与燃气公司现有的业务平台及业务数据库有机的结合

起来。

呼叫中心已经成为公认的改善服务的措施,对于燃气公司也不例外。

二、博域通讯燃气公司多媒体呼叫中心系统概述

燃气公司多媒体呼叫中心系统的基本需求如下:

人工座席数量不少于16个;

支持的通讯方式包括:电话,传真,手机;

支持不少于16路电话同时呼入;

支持不少于4路传真;

支持不少于16路IVR;

具有录音留言功能;

具有语音自动应答功能(IVR)/交互式传真应答功能(IFR),支持自动文本转语音(语音合成);

完成IVR导航(语音菜单提供普通话、广东话;文本合成为语音支持普通话)和播报;

完成座席电话转接和其他基本的话务功能;

座席具有软电话方式的主动呼出(电脑拨号打外线)功能;

实现ACD(自动坐席分配):系统将服务进行排队,然后把每一个服务都能传递给最合适的

话务员。服务的路由方法可以基于一些条件,例如,座席专业技能、空

闲率、最近解答这个客户的话务员等的信息分析,选出最合适的一个座席来为用户提供相应

的服务;

完成来电和客户资料自动显示(屏幕弹出),呼叫转移,基本系统维护管理功能,客户资料

管理功能,话务员技能分组。

主要业务功能:燃气公司方面基本法规等业务咨询用户基本价查询/气费查询,燃气抢修

申告投诉建议燃气公司费欠费催缴基本话务量和业务统计分析功能

燃气供应行业也是与百姓生活息息相关的一个公共服务事业,其用户数量庞大,服务内容丰

富、流程复杂,需要调动的业务部门多,用户对服务响应时间的要求

比较高,而且还涉及到报险抢修等紧急事故处理这样的特殊"服务"。

博域通讯燃气公司多媒体呼叫中心系统实现以统一的形象面向客户,充分利用了企业现有的

技术和资源,构筑了一个支持多种接入手段的统一接入路由、高质量

、高效率、互动的新一代客户综合服务系统,还能够在不改动系统结构的基础上以模块化方

式增加新业务。

博域通讯燃气公司多媒体呼叫中心系统采用一个特别易记的特别服务号码,向社会公布,客

户打入此电话号码进行信息查询、客户投诉建议等。客户打入电话后

,当系统的自动语音应答子系统无法解决客户问题时,客户可选择人工服务,由企业客户服

务代表直接接听客户电话,处理并解决客户问题。此时客户同座席话

务人员直接沟通,并同时记录下该客户的联系方式,将相关数据添加入系统数据库;也可以

在数据库的支持下回答信息查询等。客户也可以选择自动语音服务方

式,根据系统的语音提示输入按键,选择类别,进行修改查询密码,修改交接密码,修改交

接密文,查询客户资料。

本系统能够将数据库中每天收到的各种类型的信息进行整理后供查询,或将信息的统计报表

和其他的各种信息汇总输出,上报给相关部门或领导。各相关部门调

查处理结果和答复意见出来后,再由座席话务人员通知到本人。

也可由系统自动拨通联系电话,由系统通过传真或电脑语音自动播报调查处理结果和答复意

见来完成回馈。

功能丰富而强大的座席业务软件系统,减少了座席服务技能的差异,大大提高了业务处理效

率和服务水平。强大的统计分析工具有助于燃气公司了解客户需求,

为产品和服务调整,发展目标的制定提供强有力的数据支持。本系统建议采用基于计算机

语音板卡的语音接入方式,支持1号线路的接入,保障系统的可靠性和

稳定性,可以减少燃气公司一期工程投资,同时具有良好的系统性能。

博域通讯燃气公司多媒体呼叫中心系统在为企业提供各种各样的业务服务的同时,也向企业

提供详尽的维护管理功能。

三、博域通讯燃气公司多媒体呼叫中心系统的特色

博域通讯在国内率先采用最先进的第四代呼叫中心技术和自主研制的核心平台构建完整的

计算机电信集成(CTI)系统体系,以博域通讯一体化交换机呼叫中心平台

产品BYUNICC4.0/一体化呼叫中心平台产品BYICC2.0为技术平台,采用了具体业务和硬件分

离的设计原则,企业可根据自己的需要在基本硬件平台资源的基础上开

展多种多样的业务功能。

高智能的呼叫中心平台是建立高效的业务平台的基础,高稳定的呼叫中心平台是业务稳定运

行的基石,呼叫中心平台产品的功能和性能对客户服务中心的运营和管

理起着至关重要的作用,一体化交换机呼叫中心平台产品BYUNICC4.0/一体化呼叫中心平台

产品BYICC2.0作为业界领先的高度整合、无缝链接、性能卓越、运行稳

定、安装实施快速便捷、内置CRM功能(将呼叫中心收集到的顾客档案信息/业务咨询/业务

投诉/业务受理/主动回访/市场调查等信息进行录入/统计分析,实现统

一的客户信息管理,并及时反馈到企业产品开发以及管理决策上;实现与业务操作及企业/

政府部门的信息资源无缝集成,具有良好的企业数据融合能力和良好

的企业业务整合能力,已有的CRM系统能直接嵌入到一体化呼叫中心平台的人工座席软件

的操作界面;通过呼叫中心与客户关系管理系统相结合,实现对客户的个

性化和差异化服务,从而最终提高客户的满意度和忠诚度)、高性价比的一体化呼叫中心(CTI)

通讯平台,集成并固化了PBX/ACD/IVR/CTI/数字录音/语音信

箱/VOIP/TTS/传真/人工座席软件/短信/统计报表软件/维护管理工具软件/易学易用的二次开

发环境等核心的呼叫中心功能模块,实现了简单、高性能价格比的系

统构架,所有对平台和系统功能的修改、扩展等都不会影响到系统的正常使用,具有高度集

成的一体化技术解决方案、电信级的稳定性和迅速的灾难恢复能力、充

足的系统容量和平滑的扩展能力,以及超强的系统可维护行和高性价比等优异特性;广泛适

用于各类企业建设客户服务中心(呼叫中心,CALLCENTER)系统,政

府部门建设语音服务系统。一体化交换机呼叫中心平台产品BYUNICC4.0/一体化呼叫中心平

台产品BYICC2.0经过众多企业客户服务中心(呼叫中心,CALLCENTER

)系统以及政府部门语音服务系统的成功案例验证。

本系统具有以下几个方面的显著特点:

三层客户机/服务器软件体系结构

采用了国际领先的呼叫智能分配和路由技术,合理分配每个座席的呼叫话务量

引入自动文本转语音(TTS)技术

先进灵活的系统结构

易于和燃气公司内部MIS系统、抢修系统、营业系统高度集成,从而在信息化管理上

实现了对企业内部资源和外部资源的有效整合

话路、客户数据、操作界面的同步转移

完善的系统管理功能

严格的系统安全性设计我们主要从以下几个方面来考虑系统的安全性和可靠性设计:

双机集群,访问控制,信息传输安全,数据库安全,应用的安全

性,防病毒措施,安全备份,安全管理制度等。

支持分布式呼叫中心

电信级的应用水平

系统模块化的、领先的软硬件设计和一流性价比的的硬件设备,使得本燃气公司多媒体呼叫

中心系统达到了电信级的可靠性及可用性,性能稳定,能够保证在大

呼叫量下平稳运行。

四、博域通讯燃气公司多媒体呼叫中心系统的业务功能

客户利用电话、手机等拨打某一特服号码(如9xxxx)进入燃气公司多媒体呼叫中心系统,本

系统依托燃气公司各类业务技术支持系统和网络系统,通过人工受理或

自动语音服务等方式全天24小时不间断地为客户提供各种服务。

系统的业务功能结构如下图所示:

博域通讯燃气公司多媒体呼叫中心系统所实现的主要业务功能如下(可以根据燃气公司的要

求进行修改完善):

4.1业务咨询服务

在人工座席服务时或自动语音服务时,受理用户的业务咨询请求。主要包括:

燃气方面基本法规;

业务申办流程;

用气疑难解答等。

真正实现7*24小时业务申请服务:即使在无人值守的情况下,客户亦能通过拨打呼叫中心

热线电话号码,得到系统以语音方式进行的业务咨询服务;系统在人工

服务状态下,当业务代表输入客户名称时,系统即时将客户与企业相关的信息显示在座席终

端上,使业务及时了解客户,有针对性回答客户问题,使客户倍感亲

切。系统的自动话务分配(ACD)功能能根据客户需求,选择最合适的业务代表接听。企业

所有业务代表均是根据终端上显示回答客户,规范了语言,统一了回答

。客户有什么问题想要咨询,可以给系统工作人员留言,工作人员通过语音信箱回答客户

的问题,方便简捷。语音信箱将提供实时录音记录,避免信息遗漏。它

要求客户留下回电号码、相关问题内容及是否希望回复等信息,待座席代表有空闲时进行回

复,并将处理意见及时反馈给客户。

4.2业务查询服务

燃气公司将用户基本价,用户气费以语音,文档等方式存入系统,这样,客户通过拨打呼叫

中心热线电话,即能:☆以语音方式听取所需要的客户资料、公司

背景信息等;☆由业务代表根据终端显示,向客户进行回答问题;业务查询支持用户通

过电话、手机、传真等手段进行各种业务查询服务。

查询类业务主要提供两类服务,一类服务主要是面向客户提供对业务、服务等信息的查询;

另一类主要是面向燃气公司内部的工作人员提供有关业务资料、客户

档案等信息的查询。该类业务一方面解决了客户对业务、服务状态查询的需要,加强相互

的信任,提高服务水平;一方面又帮助了企业内部的工作人员,使他们

工作当中可以得到来自本系统的帮助。

4.3业务受理类服务

受理类业务是燃气公司多媒体呼叫中心系统的重要业务之一,也是建立优秀企业形象的主要

手段。该类业务主要包括以下几个主要内容:A通过受理功能,客户

可获得燃气抢修申告的及时受理服务。B客户信息管理客户信息包括客户编号、客户名称、

联系电话、地址、所属地区、地区编号、用户人口数、楼层等多项

,接听客户呼入电话,由座席代表记录信息形成档案,也可采用更为主动的呼出方式来确认、

核实、补充档案。

4.4用户投诉/意见建议受理

本呼叫中心系统可通过电话,手机,传真等各种接入手段接受用户的投诉,并及时处理或通

过特定的通信渠道转交给企业的处理部门处理,同时可根据处理的情

况及时回复用户,做到服务的闭环。

A当客户对燃气公司质量或输送管道,或对相关服务人员有意见时,可通过人工,留言信

箱,电话,手机,传真等方式,将自己的投诉存入系统。

B企业相关人员通过专用密码及时提取,统计,分析,及时处理,并将处理结果存入系统,

供客户查询。

主要内容包括如下:

投诉单的记录和录音功能;

投诉单的送发功能;

投诉单的处理功能;

投诉单的答复功能。对已受理的投诉举报或批评建议,系统自动生成唯一标识的受理流水

号。客户凭此流水号,可随时打电话进入系统了解处理情况。对已受

理的投诉举报或批评建议,由职能部门整理后,根据职责分工转对口部门处理。对本级部门

无法处理的举报,可采用自动或手工方式移交上级部门处理。本系统

可通过电话语音、传真等方式将处理结果及时反馈给客户。

4.5主动呼出服务

呼叫中心最具生命力的功能是呼出(OUTBOUND),通过呼出主动地为客户提供服务,才是

它的用武之地。通过这种主动的呼出,最终将为企业获取无可估量的利

润,将呼叫中心变成"利润中心"。呼出是广义的"呼出",即呼叫中心主动与客户联系的方

式,包括自动呼出、人工呼出、传真呼出,甚至上门拜访等。

利用呼叫中心自身具备的呼出功能,燃气公司可以根据自身的客户数据库主动联系客户,为

用户提供包括用户满意度调查、客户气费欠款的自动催缴等服务。A

、用户回访。了解用户对服务的满意度和具体意见。系统能在规定的时间内,按预先设置,

逐一拨号,通过主动地与固有客户,特别是大客户的联络,帮助客户

的实际问题,一方面可以加深客户感情,另一方面可以更好地把握客户需求的变化以不断改

进工作;燃气公司根据调查结果,进行统计分析,为再发展和决策提

供依据。B、客户气费欠款的自动催缴:大大减轻了工作人员的工作量,同时有助于资金的

回收,提高企业的经济效益。

4.6其他增值服务(可选)

可以根据燃气公司的要求进行定制。如:CRM-客户关系管理。

CRM系统功能描述:用户完整资料的建立与管理;用户使用中海物流服务的管理;客户营

销管理;客户综合分析。建议放在二期工程进行实施。

4.7因特网服务功能(可选)

结合Internet技术,提供客户网上自动响应,拓展服务功能;如可以在互联网上进行业务咨

询,业务查询,客户满意度调查,客户投诉建议等。采用Internet技

术,将因特网融入到本呼叫中心,实现与客户之间的Email服务、CallBack(呼叫回复)、交

互式文本交谈、浏览导航,提供网页连接/传送功能。建议放在二期

工程进行实施。

五、系统物理结构

博域通讯燃气公司呼叫中心系统由一体化交换机BYIPPBX4.0[集成并固化了PBX、CTI服务

器、ACD、IVR(交互式语音应答)服务、传真服务、VoIP、TTS服务、录

音留言服务、语音信箱服务、人工座席CTI接口、系统维护管理、数据库/录音服务器等]、

人工座席PC机(逻辑上分为:普通业务代表座席、专家/班长座席)、话

务员声导管耳机+耳机话务盒(可以采用普通电话机)、通信线路、网络系统等和呼叫中心支

撑平台(一体化交换机呼叫中心平台软件BYUNICC4.0)、经过定制的

交互式语音应答(IVR)应用软件、经过定制(或标准)的人工座席应用软件(包括录音管

理功能)、经过定制(或标准)的统计报表应用软件构成。

数据库服务器可以根据需要配置在局域网内的任何一台服务器上。

系统网络结构图如下:

博域通讯燃气公司呼叫中心系统人工座席软件示意图

博域通讯燃气公司呼叫中心系统统计报表软件示意图

博域通讯燃气公司呼叫中心系统统计报表软件示意图

硬件组成:

一体化交换机(集成并固化了PBX/ACD/IVR/CTI/数字录音/语音信箱/VOIP/TTS/传真/人工

座席软件/短信/统计报表软件/维护管理工具软件/易学易用的二

次开发环境等核心的呼叫中心功能模块);

人工座席使用的普通PC机若干台;

话务员耳机以及话务盒(或标准电话机)若干只;

局域网和配件以及通信线路(中继线路以及分机线路);

数据库服务器(对于中小型系统,可以使用一体化交换机兼作为数据库服务器);

WEB/EMAIL服务器(可选);

短信息网关服务器以及GPRS短信猫(可选)

软件组成:

底层支撑平台软件BYUNICCSS2.0;

自动语音流程(IVR/IFR)应用软件BYUNICCIVR2.0,可定制[可以利用产品内置的可视化

的IVR流程图形编辑环境进行编辑定制];

人工座席软件BYUNICCAgent2.0,可定制;

统计报表软件BYUNICCReport2.0,可定制;

业务应用网关软件BYUNICCGateWay2.0(可选),可定制;

同步录音管理软件BYUNICCRecMan2.0(可选);

系统维护管理软件BYUNICCManager2.0;

TTS语音合成引擎软件BYUNICCTTS2.0(可选);

自动传真收发软件BYUNICCFAX2.0(可选);

系统通信实时监控软件BYUNICCMONITOR2.0;

短信平台软件BYUNICCSMS2.0(可选)

五、深圳博域通讯一体化交换机呼叫中心平台产品BYUNICC4.0/一体化呼叫中心平台产品

BYICC2.0的部分燃气客户服务中心系统成功案例

南宁市安拓软件有限公司采用博域通讯一体化呼叫中心平台产品BYICC2.0开发建设南宁市

海方燃气有限责任公司客户服务中心(CallCenter)系统。(2009-6-19

procedureParseAttributes(constAValue:string;Start,Close:integer;Attributes:TStrings);

//ConverttheattributesstringAValuein[Start,Close-1]totheattributesstringlist

var

i:integer;

InQuotes:boolean;

AQuoteChar:char;

begin

InQuotes:=False;

AQuoteChar:='"';

ifnotassigned(Attributes)then

exit;

ifnotTrimPos(AValue,Start,Close)then

exit;

//Clearfirst

;

//Loopthroughcharacters

fori:=StarttoClose-1do

begin

//Inquotes?

ifInQuotesthen

begin

ifAValue[i]=AQuoteCharthen

InQuotes:=False;

endelse

begin

ifAValue[i]incQuoteCharsthen

begin

InQuotes:=True;

AQuoteChar:=AValue[i];

end;

end;

//Addattributestringsoneachcontrolcharbreak

ifnotInQuotesthen

ifAValue[i]incControlCharsthen

begin

ifi>Startthen

(copy(AValue,Start,i-Start));

Start:=i+1;

end;

end;

//Addlastattributestring

ifStart

(copy(AValue,Start,Close-Start));

//First-char"="signsshouldappendtoprevious

fori:=-1downto1do

ifAttributes[i][1]='='then

begin

Attributes[i-1]:=Attributes[i-1]+Attributes[i];

(i);

end;

//First-charquotesshouldappendtoprevious

fori:=-1downto1do

if(Attributes[i][1]incQuoteChars)and(Pos('=',Attributes[i-1])>0)then

begin

Attributes[i-1]:=Attributes[i-1]+Attributes[i];

(i);

end;

end;

functionTrimPos(constAValue:string;varStart,Close:integer):boolean;

//TrimthestringinAValuein[Start,Close-1]byadjustingStartandClosevariables

begin

//Checks

Start:=Max(1,Start);

Close:=Min(Length(AValue)+1,Close);

ifClose<=Startthen

begin

Result:=False;

exit;

end;

//Trimleft

while

(Start

(AValue[Start]incControlChars)do

inc(Start);

//Trimright

while

(Start

(AValue[Close-1]incControlChars)do

dec(Close);

//Dowehaveastringleft?

Result:=Close>Start;

end;

procedureWriteStringToStream(S:TStream;constAString:string);

begin

ifLength(AString)>0then

begin

{$IFDEFCLR}

(BytesOf(AString),Length(AString));

{$ELSE}

(AString[1],Length(AString));

{$ENDIF}

end;

end;

functionReadOpenTag(AReader:TsdSurplusReader):integer;

//TrytoreadthetypeofopentagfromS

var

AIndex,i:integer;

Found:boolean;

Ch:char;

Candidates:array[0..cTagCount-1]ofboolean;

Surplus:string;

begin

Surplus:='';

Result:=cTagCount-1;

fori:=0tocTagCount-1doCandidates[i]:=True;

AIndex:=1;

repeat

Found:=False;

inc(AIndex);

ar(Ch)=0then

exit;

Surplus:=Surplus+Ch;

fori:=cTagCount-1downto0do

ifCandidates[i]and(length(cTags[i].FStart)>=AIndex)then

begin

ifcTags[i].FStart[AIndex]=Chthen

begin

Found:=True;

iflength(cTags[i].FStart)=AIndexthen

Result:=i;

endelse

Candidates[i]:=False;

end;

untilFound=False;

//Thesurplusstringthatwealreadyread(everythingafterthetag)

s:=copy(Surplus,length(cTags[Result].FStart),length(Surplus));

end;

functionReadStringFromStreamUntil(AReader:TsdSurplusReader;constASearch:string;

varAValue:string;SkipQuotes:boolean):boolean;

var

AIndex,ValueIndex,SearchIndex:integer;

LastSearchChar,Ch:char;

InQuotes:boolean;

QuoteChar:Char;

SB:TsdStringBuilder;

begin

Result:=False;

InQuotes:=False;

//Getlastsearchstringcharacter

AIndex:=length(ASearch);

ifAIndex=0thenexit;

LastSearchChar:=ASearch[AIndex];

SB:=;

try

QuoteChar:=#0;

repeat

//Addcharacterstothevaluetobereturned

ar(Ch)=0then

exit;

r(Ch);

//Doweskipquotes?

ifSkipQuotesthen

begin

ifInQuotesthen

begin

if(Ch=QuoteChar)then

InQuotes:=false;

endelse

begin

ifChincQuoteCharsthen

begin

InQuotes:=true;

QuoteChar:=Ch;

end;

end;

end;

//Inquotes?Ifso,wedon'tchecktheendcondition

ifnotInQuotesthen

begin

//Isthelastcharthesameasthelastcharofthesearchstring?

ifCh=LastSearchCharthen

begin

//Checktoseeifthewholesearchstringispresent

ValueIndex:=-1;

SearchIndex:=length(ASearch)-1;

ifValueIndex

Result:=True;

while(SearchIndex>0)andResultdo

begin

Result:=SB[ValueIndex]=ASearch[SearchIndex];

dec(ValueIndex);

dec(SearchIndex);

end;

end;

end;

untilResult;

//Useonlythepartbeforethesearchstring

AValue:=Copy(1,-length(ASearch));

finally

;

end;

end;

functionReadStringFromStreamWithQuotes(S:TStream;constTerminator:string;

varAValue:string):boolean;

var

Ch,QuoteChar:char;

InQuotes:boolean;

SB:TsdStringBuilder;

begin

SB:=;

try

QuoteChar:=#0;

Result:=False;

InQuotes:=False;

repeat

(Ch,1)=0thenexit;

ifnotInQuotesthen

begin

if(Ch='"')or(Ch='''')then

begin

InQuotes:=True;

QuoteChar:=Ch;

end;

endelse

begin

ifCh=QuoteCharthen

InQuotes:=False;

end;

ifnotInQuotesand(Ch=Terminator)then

break;

r(Ch);

untilFalse;

AValue:=;

Result:=True;

finally

;

end;

end;

functionsdDateTimeFromString(constADate:string):TDateTime;

//ConvertthestringADatetoaTDateTimeaccordingtotheW3Cdate/timespecification

//asfoundhere:/TR/NOTE-datetime

var

AYear,AMonth,ADay,AHour,AMin,ASec,AMSec:word;

begin

AYear:=StrToInt(copy(ADate,1,4));

AMonth:=StrToInt(copy(ADate,6,2));

ADay:=StrToInt(copy(ADate,9,2));

ifLength(ADate)>16then

begin

AHour:=StrToInt(copy(ADate,12,2));

AMin:=StrToInt(copy(ADate,15,2));

ASec:=StrToIntDef(copy(ADate,18,2),0);//Theymightbeomitted,sodefaultto0

AMSec:=StrToIntDef(copy(ADate,21,3),0);//Theymightbeomitted,sodefaultto0

endelse

begin

AHour:=0;

AMin:=0;

ASec:=0;

AMSec:=0;

end;

Result:=

EncodeDate(AYear,AMonth,ADay)+

EncodeTime(AHour,AMin,ASec,AMSec);

end;

functionsdDateTimeFromStringDefault(constADate:string;ADefault:TDateTime):TDateTime;

//ConvertthestringADatetoaTDateTimeaccordingtotheW3Cdate/timespecification

//asfoundhere:/TR/NOTE-datetime

//Ifthereisaconversionerror,thedefaultvalueADefaultisreturned.

begin

try

Result:=sdDateTimeFromString(ADate);

except

Result:=ADefault;

end;

end;

functionsdDateTimeToString(ADate:TDateTime):string;

//ConverttheTDateTimeADatetoastringaccordingtotheW3Cdate/timespecification

//asfoundhere:/TR/NOTE-datetime

var

AYear,AMonth,ADay,AHour,AMin,ASec,AMSec:word;

begin

DecodeDate(ADate,AYear,AMonth,ADay);

DecodeTime(ADate,AHour,AMin,ASec,AMSec);

iffrac(ADate)=0then

Result:=Format('%.4d-%.2d-%.2d',[AYear,AMonth,ADay])

else

Result:=Format('%.4d-%.2d-%.2dT%.2d:%.2d:%.2d.%.3dZ',

[AYear,AMonth,ADay,AHour,AMin,ASec,AMSec]);

end;

functionsdWriteNumber(Value:double;SignificantDigits:integer;AllowScientific:boolean):

string;

const

Limits:array[1..9]ofinteger=

(10,100,1000,10000,100000,1000000,10000000,100000000,1000000000);

var

Limit,Limitd,PointPos,IntVal,ScPower:integer;

Body:string;

begin

if(SignificantDigits<1)or(SignificantDigits>9)then

(sxeSignificantDigitsOutOfRange);

//Zero

ifValue=0then

begin

Result:='0';

exit;

end;

//Sign

ifValue<0then

begin

Result:='-';

Value:=-Value;

endelse

Result:='';

//Determinepointposition

Limit:=Limits[SignificantDigits];

Limitd:=Limitdiv10;

PointPos:=SignificantDigits;

whileValue

begin

Value:=Value*10;

dec(PointPos);

end;

whileValue>=Limitdo

begin

Value:=Value*0.1;

inc(PointPos);

end;

//Round

IntVal:=round(Value);

//Exceptionalcasewhichhappenswhenthevalueroundsuptothelimit

ifIntval=Limitthen

begin

IntVal:=IntValdiv10;

inc(PointPos);

end;

//Stripoffanyzeros,thesereducesignificancecount

while(IntValmod10=0)and(PointPos

begin

dec(SignificantDigits);

IntVal:=IntValdiv10;

end;

//Checkforscientificnotation

ScPower:=0;

ifAllowScientificand((PointPos<-1)or(PointPos>SignificantDigits+2))then

begin

ScPower:=PointPos-1;

dec(PointPos,ScPower);

end;

//Body

Body:=IntToStr(IntVal);

whilePointPos>SignificantDigitsdo

begin

Body:=Body+'0';

inc(SignificantDigits);

end;

whilePointPos<0do

begin

Body:='0'+Body;

inc(PointPos);

end;

ifPointPos=0then

Body:='.'+Body

else

ifPointPos

Body:=copy(Body,1,PointPos)+'.'+copy(Body,PointPos+1,SignificantDigits);

//Finalresult

ifScPower=0then

Result:=Result+Body

else

Result:=Result+Body+'E'+IntToStr(ScPower);

end;

{$IFDEFCLR}

functionsdUnicodeToUtf8(constW:widestring):string;

begin

Result:=es(W);

end;

functionsdUtf8ToUnicode(constS:string):widestring;

begin

Result:=ing(BytesOf(S));

end;

functionEncodeBase64Buf(constBuffer:TBytes;Count:Integer):string;

begin

Result:=64String(Buffer,0,Count);

end;

functionEncodeBase64(constSource:string):string;

begin

Result:=64String(BytesOf(Source));

end;

procedureDecodeBase64Buf(constSource:string;varBuffer:TBytes;Count:Integer);

var

ADecoded:TBytes;

begin

ADecoded:=se64String(Source);

ifCount>Length(ADecoded)then

(sxeMissingDataInBinaryStream);

SetLength(ADecoded,Count);

Buffer:=ADecoded;

end;

functionDecodeBase64(constSource:string):string;

begin

Result:=AnsiString(se64String(Source));

end;

{$ELSE}

functionPtrUnicodeToUtf8(Dest:PChar;MaxDestBytes:Cardinal;Source:PWideChar;

SourceChars:Cardinal):Cardinal;

var

i,count:Cardinal;

c:Cardinal;

begin

Result:=0;

ifnotassigned(Source)ornotassigned(Dest)then

exit;

count:=0;

i:=0;

while(i

begin

c:=Cardinal(Source[i]);

Inc(i);

ifc<=$7Fthen

begin

Dest[count]:=Char(c);

Inc(count);

endelse

ifc>$7FFthen

begin

ifcount+3>MaxDestBytesthen

break;

Dest[count]:=Char($E0or(cshr12));

Dest[count+1]:=Char($80or((cshr6)and$3F));

Dest[count+2]:=Char($80or(cand$3F));

Inc(count,3);

endelse

begin//$7F

ifcount+2>MaxDestBytesthen

break;

Dest[count]:=Char($C0or(cshr6));

Dest[count+1]:=Char($80or(cand$3F));

Inc(count,2);

end;

end;

ifcount>=MaxDestBytesthen

count:=MaxDestBytes-1;

Dest[count]:=#0;

Result:=count+1;//convertzerobasedindextobytecount

end;

functionPtrUtf8ToUnicode(Dest:PWideChar;MaxDestChars:Cardinal;Source:PChar;

SourceBytes:Cardinal):Cardinal;

var

i,count:Cardinal;

c:Byte;

wc:Cardinal;

begin

ifnotassigned(Dest)ornotassigned(Source)then

begin

Result:=0;

Exit;

end;

Result:=Cardinal(-1);

count:=0;

i:=0;

while(i

begin

wc:=Cardinal(Source[i]);

Inc(i);

if(wcand$80)<>0then

begin

ifi>=SourceBytesthen

//incompletemultibytechar

Exit;

wc:=wcand$3F;

if(wcand$20)<>0then

begin

c:=Byte(Source[i]);

Inc(i);

if(cand$C0)<>$80then

//malformedtrailbyteoroutofrangechar

Exit;

ifi>=SourceBytesthen

//incompletemultibytechar

Exit;

wc:=(wcshl6)or(cand$3F);

end;

c:=Byte(Source[i]);

Inc(i);

if(cand$C0)<>$80then

//malformedtrailbyte

Exit;

Dest[count]:=WideChar((wcshl6)or(cand$3F));

endelse

Dest[count]:=WideChar(wc);

Inc(count);

end;

ifcount>=MaxDestCharsthen

count:=MaxDestChars-1;

Dest[count]:=#0;

Result:=count+1;

end;

functionsdUnicodeToUtf8(constW:widestring):string;

var

L:integer;

Temp:string;

begin

Result:='';

ifW=''thenExit;

SetLength(Temp,Length(W)*3);//SetLengthincludesspacefornullterminator

L:=PtrUnicodeToUtf8(PChar(Temp),Length(Temp)+1,PWideChar(W),Length(W));

ifL>0then

SetLength(Temp,L-1)

else

Temp:='';

Result:=Temp;

end;

functionsdUtf8ToUnicode(constS:string):widestring;

var

L:Integer;

Temp:WideString;

begin

Result:='';

ifS=''thenExit;

SetLength(Temp,Length(S));

L:=PtrUtf8ToUnicode(PWideChar(Temp),Length(Temp)+1,PChar(S),Length(S));

ifL>0then

SetLength(Temp,L-1)

else

Temp:='';

Result:=Temp;

end;

functionEncodeBase64Buf(constBuffer;Count:Integer):string;

var

i,j:integer;

ACore:integer;

ALong:cardinal;

S:PByte;

begin

//MakesureASizeisalwaysamultipleof3,andthismultiple

//getssavedas4characters

ACore:=(Count+2)div3;

//Setthelengthofthestringthatstoresencodedcharacters

SetLength(Result,ACore*4);

S:=@Buffer;

//DotheloopACoretimes

fori:=0toACore-1do

begin

ALong:=0;

forj:=0to2do

begin

ALong:=ALongshl8+S^;

inc(S);

end;

forj:=0to3do

begin

Result[i*4+4-j]:=cBase64Char[ALongand$3F];

ALong:=ALongshr6;

end;

end;

//ForcomformitytoBase64,wemustpadthedatainsteadofzeroout

//ifthesizeisnotanexactmultipleof3

caseACore*3-Countof

0:;//nothingtodo

1://padonebyte

Result[ACore*4]:=cBase64PadChar;

2://padtwobytes

begin

Result[ACore*4]:=cBase64PadChar;

Result[ACore*4-1]:=cBase64PadChar;

end;

end;//case

end;

functionEncodeBase64(constSource:string):string;

//ctionreturnstheBASE64encoded

//dataasstring,withoutanylinebreaks.

begin

iflength(Source)>0then

Result:=EncodeBase64Buf(Source[1],length(Source))

else

Result:='';

end;

procedureDecodeBase64Buf(varSource:string;varBuffer;Count:Integer);

var

i,j:integer;

BufPos,Core:integer;

LongVal:cardinal;

D:PByte;

Map:array[Char]ofbyte;

begin

//Core*4isthenumberofcharstoread-checklength

Core:=Length(Source)div4;

ifCount>Core*3then

(sxeMissingDataInBinaryStream);

//Preparemap

fori:=0to63do

Map[cBase64Char[i]]:=i;

D:=@Buffer;

//Checkforfinalpadding,andreplacewith"zeros".Therecanbe

//atmaxtwopadchars('=')

BufPos:=length(Source);

if(BufPos>0)and(Source[BufPos]=cBase64PadChar)then

begin

Source[BufPos]:=cBase64Char[0];

dec(BufPos);

if(BufPos>0)and(Source[BufPos]=cBase64PadChar)then

Source[BufPos]:=cBase64Char[0];

end;

//DothisCoretimes

fori:=0toCore-1do

begin

LongVal:=0;

//Unrollthecharacters

forj:=0to3do

LongVal:=LongValshl6+Map[Source[i*4+j+1]];

//andunrollthebytes

forj:=2downto0do

begin

//Checkovershoot

ifinteger(D)-integer(@Buffer)>=Countthen

exit;

D^:=LongValshr(j*8)and$FF;

inc(D);

end;

end;

end;

functionDecodeBase64(constSource:string):string;

//ctionreturnsthebinary

//tringStreamtoconvertthisdatatoastream.

var

BufData:string;

BufSize,BufPos:integer;

begin

BufData:=RemoveControlChars(Source);

//Determinelengthofdata

BufSize:=length(BufData)div4;

ifBufSize*4<>length(BufData)then

(sxeErrorCalcStreamLength);

BufSize:=BufSize*3;

//Checkpaddingchars

BufPos:=length(BufData);

if(BufPos>0)and(BufData[BufPos]=cBase64PadChar)then

begin

dec(BufPos);

dec(BufSize);

if(BufPos>0)and(BufData[BufPos]=cBase64PadChar)then

dec(BufSize);

end;

Setlength(Result,BufSize);

//Decode

ifBufSize>0then

DecodeBase64Buf(BufData,Result[1],BufSize);

end;

{$ENDIF}

functionsdAnsiToUtf8(constS:string):string;

begin

Result:=sdUnicodeToUtf8(S);

end;

functionsdUtf8ToAnsi(constS:string):string;

begin

Result:=sdUtf8ToUnicode(S);

end;

functionEncodeBinHexBuf(constSource;Count:Integer):string;

//ctionreturnstheBINHEXencoded

//dataasstring,withoutanylinebreaks.

var

{$IFDEFCLR}

Text:TBytes;

{$ELSE}

Text:string;

{$ENDIF}

begin

SetLength(Text,Count*2);

{$IFDEFCLR}

BinToHex(TBytes(Source),0,Text,0,Count);

{$ELSE}

{$IFDEFD4UP}

BinToHex(PChar(@Source),PChar(Text),Count);

{$ELSE}

(sxeUnsupportedEncoding);

{$ENDIF}

{$ENDIF}

Result:=Text;

end;

functionEncodeBinHex(constSource:string):string;

//ctionreturnstheBINHEXencoded

//dataasstring,withoutanylinebreaks.

var

{$IFDEFCLR}

Text:TBytes;

{$ELSE}

Text:string;

{$ENDIF}

begin

SetLength(Text,Length(Source)*2);

{$IFDEFCLR}

BinToHex(BytesOf(Source),0,Text,0,Length(Source));

{$ELSE}

{$IFDEFD4UP}

BinToHex(PChar(Source),PChar(Text),Length(Source));

{$ELSE}

(sxeUnsupportedEncoding);

{$ENDIF}

{$ENDIF}

Result:=Text;

end;

procedureDecodeBinHexBuf(constSource:string;varBuffer{$IFDEFCLR}:TBytes{$ENDIF};Count:

Integer);

//DecodeBINHEXdatainSourceintobinarydata.

begin

ifLength(Source)div2

(sxeMissingDataInBinaryStream);

{$IFDEFCLR}

HexToBin(BytesOf(Source),0,Buffer,0,Count);

{$ELSE}

{$IFDEFD4UP}

HexToBin(PChar(Source),PChar(@Buffer),Count);

{$ELSE}

(sxeUnsupportedEncoding);

{$ENDIF}

{$ENDIF}

end;

functionDecodeBinHex(constSource:string):string;

//ctionreturnsthebinary

//tringStreamtoconvertthisdatatoastream.

var

AData:string;

ASize:integer;

{$IFDEFCLR}

Buffer:TBytes;

{$ELSE}

Buffer:string;

{$ENDIF}

begin

AData:=RemoveControlChars(Source);

//Determinelengthofdata

ASize:=length(AData)div2;

ifASize*2<>length(AData)then

(sxeErrorCalcStreamLength);

SetLength(Buffer,ASize);

{$IFDEFCLR}

HexToBin(BytesOf(AData),0,Buffer,0,ASize);

{$ELSE}

{$IFDEFD4UP}

HexToBin(PChar(AData),PChar(Buffer),ASize);

{$ELSE}

(sxeUnsupportedEncoding);

{$ENDIF}

{$ENDIF}

Result:=Buffer;

end;

functionsdStringToBool(constAValue:string):boolean;

var

Ch:Char;

begin

ifLength(AValue)>0then

begin

Ch:=UpCase(AValue[1]);

ifChin['T','Y']then

begin

Result:=True;

exit;

end;

ifChin['F','N']then

begin

Result:=False;

exit;

end;

end;

(sxeCannotConverToBool);

end;

functionsdStringFromBool(ABool:boolean):string;

const

cBoolValues:array[boolean]ofstring=('False','True');

begin

Result:=cBoolValues[ABool];

end;

{TXmlNode}

arsing:boolean;

begin

Result:=assigned(Document)arsing;

end;

(Source:TPersistent);

var

i:integer;

Node:TXmlNode;

begin

ifSourceisTXmlNodethen

begin

//Clearfirst

Clear;

//Properties

FElementType:=TXmlNode(Source).FElementType;

FName:=TXmlNode(Source).FName;

FTag:=TXmlNode(Source).FTag;

FValue:=TXmlNode(Source).FValue;

//Attributes

ifassigned(TXmlNode(Source).FAttributes)then

begin

CheckCreateAttributesList;

(TXmlNode(Source).FAttributes);

end;

//Nodes

fori:=0toTXmlNode(Source).NodeCount-1do

begin

Node:=NodeNew('');

(TXmlNode(Source).Nodes[i]);

end;

endelse

ifSourceisTNativeXmlthen

begin

Assign(TNativeXml(Source).FRootNodes);

endelse

inherited;

end;

uteAdd(constAName,AValue:string);

var

Attr:string;

begin

Attr:=Format('%s=%s',[AName,QuoteString(EscapeString(AValue))]);

CheckCreateAttributesList;

(Attr);

end;

{$IFDEFD4UP}

uteAdd(constAName:string;AValue:integer);

begin

AttributeAdd(AName,IntToStr(AValue));

end;

{$ENDIF}

uteDelete(Index:integer);

begin

if(Index>=0)and(Index

(Index);

end;

uteExchange(Index1,Index2:integer);

var

Temp:string;

begin

if(Index1<>Index2)and

(Index1>=0)and(Index1<)and

(Index2>=0)and(Index2<)then

begin

Temp:=FAttributes[Index1];

FAttributes[Index1]:=FAttributes[Index2];

FAttributes[Index2]:=Temp;

end;

end;

uteIndexByname(constAName:string):integer;

//ReturntheindexoftheattributewithnameAName,or-1ifnotfound

var

i:integer;

begin

Result:=-1;

fori:=0toAttributeCount-1do

ifAnsiCompareText(AttributeName[i],AName)=0then

begin

Result:=i;

exit;

end;

end;

utesClear;

begin

FreeAndNil(FAttributes);

end;

Length:integer;

var

BufData:string;

BufPos:integer;

begin

BufData:=RemoveControlChars(FValue);

caseBinaryEncodingof

xbeBinHex:

begin

Result:=length(BufData)div2;

ifResult*2<>length(BufData)then

(sxeErrorCalcStreamLength);

end;

xbeBase64:

begin

Result:=length(BufData)div4;

ifResult*4<>length(BufData)then

(sxeErrorCalcStreamLength);

Result:=Result*3;

//Checkpaddingchars

BufPos:=length(BufData);

if(BufPos>0)and(BufData[BufPos]=cBase64PadChar)then

begin

dec(BufPos);

dec(Result);

if(BufPos>0)and(BufData[BufPos]=cBase64PadChar)then

dec(Result);

end;

end;

else

Result:=0;//avoidcompilerwarning

end;

end;

Read(varBuffer{$IFDEFCLR}:TBytes{$ENDIF};Count:Integer);

//ReaddatafromXMLbinhextothebuffer

var

BufData:string;

begin

BufData:=RemoveControlChars(FValue);

caseBinaryEncodingof

xbeBinHex:

DecodeBinHexBuf(BufData,Buffer,Count);

xbeBase64:

DecodeBase64Buf(BufData,Buffer,Count);

end;

end;

Write(constBuffer{$IFDEFCLR}:TBytes{$ENDIF};Count:Integer);

//WritedatafromthebuffertoXMLinbinhexformat

var

BufData:string;

begin

ifCount>0then

caseBinaryEncodingof

xbeBinHex:

BufData:=EncodeBinHexBuf(Buffer,Count);

xbeBase64:

BufData:=EncodeBase64Buf(Buffer,Count);

end;

//ForcomformitywithBase64,wemustaddlinebreakseach76characters

FValue:=AddControlChars(BufData,GetLineFeed+GetIndent,76);

end;

Document(ADocument:TNativeXml);

var

i:integer;

begin

FDocument:=ADocument;

fori:=0toNodeCount-1do

Nodes[i].ChangeDocument(ADocument);

end;

reateAttributesList;

begin

ifnotassigned(FAttributes)then

begin

FAttributes:=;

ifassigned(FDocument)then

:=tributes;

end;

end;

;

begin

//Name+value

FName:='';

FValue:='';

//Clearattributesandnodes

AttributesClear;

NodesClear;

end;

eNodeName(constNodeName:string):integer;

begin

//ComparewithFullPathorlocalnamebasedonNodeName'sfirstcharacter

iflength(NodeName)>0then

ifNodeName[1]='/'then

begin

//FullPath

Result:=AnsiCompareText(FullPath,NodeName);

exit;

end;

//localname

Result:=AnsiCompareText(Name,NodeName);

end;

(ADocument:TNativeXml);

begin

inheritedCreate;

FDocument:=ADocument;

end;

Name(ADocument:TNativeXml;

constAName:string);

begin

Create(ADocument);

Name:=AName;

end;

NameValue(ADocument:TNativeXml;constAName,

AValue:string);

begin

Create(ADocument);

Name:=AName;

ValueAsString:=AValue;

end;

Type(ADocument:TNativeXml;

AType:TXmlElementType);

begin

Create(ADocument);

FElementType:=AType;

end;

;

begin

ifassigned(Parent)then

move(Self);

end;

EmptyAttributes;

var

i:integer;

V:string;

begin

fori:=AttributeCount-1downto0do

begin

V:=AttributeValue[i];

iflength(V)=0then

(i);

end;

end;

EmptyNodes;

var

i:integer;

Node:TXmlNode;

begin

fori:=NodeCount-1downto0do

begin

Node:=Nodes[i];

//Recursivecall

EmptyNodes;

//Checkifweshoulddeletechildnode

ythen

NodeDelete(i);

end;

end;

y;

begin

NodesClear;

AttributesClear;

inherited;

end;

de(constNodeName:string):TXmlNode;

//rytotheNodeByName

//function,thisfunctionwillsearchthewholesubnodetree,usingthe

//DepthFirstmethod.

var

i:integer;

begin

Result:=nil;

//Loopthroughallsubnodes

fori:=0toNodeCount-1do

begin

Result:=Nodes[i];

//IfthesubnodehasnameNodeNamethenwehavearesult,exit

eNodeName(NodeName)=0then

exit;

//Ifnot,wewillsearchthesubtreeofthisnode

Result:=de(NodeName);

ifassigned(Result)then

exit;

end;

end;

des(constNodeName:string;constAList:TList);

//local

procedureFindNodesRecursive(ANode:TXmlNode;AList:TList);

var

i:integer;

begin

withANodedo

fori:=0toNodeCount-1do

begin

ifNodes[i].CompareNodeName(NodeName)=0then

(Nodes[i]);

FindNodesRecursive(Nodes[i],AList);

end;

end;

//main

begin

;

FindNodesRecursive(Self,AList);

end;

llowScientific:boolean;

begin

ifassigned(Document)then

Result:=llowScientific

else

Result:=cDefaultFloatAllowScientific;

end;

ignificantDigits:integer;

begin

ifassigned(Document)then

Result:=ignificantDigits

else

Result:=cDefaultFloatSignificantDigits;

end;

siString(consts:string):string;

begin

ifUtf8Encodedthen

Result:=sdAnsiToUtf8(s)

else

Result:=s;

end;

destring(constW:widestring):string;

begin

ifUtf8Encodedthen

Result:=sdUnicodeToUtf8(W)

else

Result:=W;

end;

ributeByName(constAName:string):string;

begin

ifassigned(FAttributes)then

Result:=UnEscapeString(UnQuoteString([AName]))

else

Result:='';

end;

ributeByNameWide(constAName:string):widestring;

begin

Result:=ToWidestring(GetAttributeByName(AName));

end;

ributeCount:integer;

begin

ifassigned(FAttributes)then

Result:=

else

Result:=0;

end;

ributeName(Index:integer):string;

begin

if(Index>=0)and(Index

Result:=[Index];

end;

ributePair(Index:integer):string;

begin

if(Index>=0)and(Index

Result:=FAttributes[Index];

end;

ributeValue(Index:integer):string;

var

P:integer;

S:string;

begin

Result:='';

if(Index>=0)and(Index

begin

S:=FAttributes[Index];

P:=AnsiPos('=',S);

ifP>0then

Result:=UnEscapeString(UnQuoteString(Copy(S,P+1,MaxInt)));

end;

end;

ributeValueAsInteger(Index:integer):integer;

begin

Result:=StrToIntDef(GetAttributeValue(Index),0);

end;

ributeValueAsWidestring(Index:integer):widestring;

begin

Result:=ToWidestring(GetAttributeValue(Index));

end;

ributeValueDirect(Index:integer):string;

var

P:integer;

S:string;

begin

Result:='';

if(Index>=0)and(Index

begin

S:=FAttributes[Index];

P:=AnsiPos('=',S);

ifP>0then

Result:=UnQuoteString(Copy(S,P+1,MaxInt));

end;

end;

aryEncoding:TBinaryEncodingType;

begin

Result:=xbeBinHex;

ifassigned(Document)then

Result:=Encoding;

end;

aryString:string;

//GetthebinarycontentsofthisnodeasBase64andreturnitasastring

var

OldEncoding:TBinaryEncodingType;

{$IFDEFCLR}

Buffer:TBytes;

{$ENDIF}

begin

//Settobase64

OldEncoding:=BinaryEncoding;

try

BinaryEncoding:=xbeBase64;

{$IFDEFCLR}

SetLength(Buffer,BufferLength);

iflength(Buffer)>0then

BufferRead(Buffer,length(Buffer));

Result:=Buffer;

{$ELSE}

SetLength(Result,BufferLength);

iflength(Result)>0then

BufferRead(Result[1],length(Result));

{$ENDIF}

finally

BinaryEncoding:=OldEncoding;

end;

end;

cadedName:string;

//Returnthename+indexandallpredecessorswithunderscorestoseparate,in

//ordertogetauniquereferencethatcanbeusedinfilenames

var

LName:string;

begin

LName:=Format('%s%.4d',[Name,StrToIntDef(AttributeByName['Index'],0)]);

ifassigned(Parent)then

Result:=Format('%s_%s',[edName,LName])

else

Result:=LName;

end;

lPath:string;

//GetFullpathwillreturnthecompletepathofthenodefromtheroot,e.g.

///Root/SubNode1/SubNode2/ThisNode

begin

Result:='/'+Name;

ifTreedepth>0then

//Recursivecall

Result:=lPath+Result;

end;

ent:string;

var

i:integer;

begin

ifassigned(Document)then

begin

matof

xfCompact:Result:='';

xfReadable:

fori:=0toTreeDepth-1do

Result:=Result+String;

end;//case

endelse

Result:=''

end;

eFeed:string;

begin

ifassigned(Document)then

begin

matof

xfCompact:Result:='';

xfReadable:Result:=#13#10;

else

Result:=#10;

end;//case

endelse

Result:='';

end;

eCount:integer;

begin

ifAssigned(FNodes)then

Result:=

else

Result:=0;

end;

es(Index:integer):TXmlNode;

begin

if(Index>=0)and(Index

Result:=TXmlNode(FNodes[Index])

else

Result:=nil;

end;

alNodeCount:integer;

var

i:integer;

begin

Result:=NodeCount;

fori:=0toNodeCount-1do

inc(Result,Nodes[i].TotalNodeCount);

end;

eDepth:integer;

begin

Result:=-1;

ifassigned(Parent)then

Result:=pth+1;

end;

ueAsBool:boolean;

begin

Result:=sdStringToBool(FValue);

end;

ueAsDateTime:TDateTime;

begin

Result:=sdDateTimeFromString(ValueAsString);

end;

ueAsFloat:double;

var

Code:integer;

begin

val(StringReplace(FValue,',','.',[]),Result,Code);

ifCode>0then

(sxeCannotConvertToFloat);

end;

ueAsInt64:int64;

begin

Result:=StrToInt64(FValue);

end;

ueAsInteger:integer;

begin

Result:=StrToInt(FValue);

end;

ueAsString:string;

begin

Result:=UnEscapeString(FValue);

end;

ueAsWidestring:widestring;

begin

Result:=ToWidestring(ValueAsString);

end;

teOnDefault:boolean;

begin

Result:=True;

ifassigned(Document)then

Result:=nDefault;

end;

ribute(constAName:string):boolean;

var

i:integer;

begin

Result:=False;

fori:=0toAttributeCount-1do

ifAnsiCompareText(AName,AttributeName[i])=0then

begin

Result:=True;

exit;

end;

end;

nParent:integer;

//Retrieveourindexintheparent'snodelist

var

i:integer;

begin

Result:=-1;

ifassigned(Parent)then

fori:=unt-1do

ifSelf=[i]then

begin

Result:=i;

exit;

end;

end;

r:boolean;

begin

Result:=(Length(FName)=0)andIsEmpty;

end;

y:boolean;

begin

Result:=(Length(FValue)=0)and(NodeCount=0)and(AttributeCount=0);

end;

lTo(ANode:TXmlNode;Options:TXmlCompareOptions;

MismatchNodes:TList):boolean;

var

i,Index:integer;

NodeResult,ChildResult:boolean;

begin

//Startwithanegativeresult

Result:=False;

NodeResult:=False;

ifnotassigned(ANode)then

exit;

//Assumechildsequalsothernode'schilds

ChildResult:=True;

//childnodenamesandvalues-thiscomesfirsttoassurethelistsarefilled

if(xcChildNamesinOptions)or(xcChildValuesinOptions)or(xcRecursiveinOptions)then

fori:=0toNodeCount-1do

begin

//Dochildnamecheck

Index:=dexByName(Nodes[i].Name);

//Dowehavethechildnodeintheother?

ifIndex<0then

begin

//Nowedonthaveit

ifxcChildNamesinOptionsthen

begin

ifassigned(MismatchNodes)(Nodes[i]);

ChildResult:=False;

end;

endelse

begin

//Dochildvaluecheck

ifxcChildValuesinOptionsthen

ifAnsiCompareText(Nodes[i].ValueAsString,[Index].ValueAsString)<>0

then

begin

ifassigned(MismatchNodes)then

(Nodes[i]);

ChildResult:=False;

end;

//Dorecursivecheck

ifxcRecursiveinOptionsthen

ifnotNodes[i].IsEqualTo([Index],Options,MismatchNodes)then

ChildResult:=False;

end;

end;

try

//Weassumetherearedifferences

NodeResult:=False;

//Nodename,typeandvalue

ifxcNodeNameinOptionsthen

ifAnsiCompareText(Name,)<>0then

exit;

ifxcNodeTypeinOptionsthen

ifElementType<>tTypethen

exit;

ifxcNodeValueinOptionsthen

ifAnsiCompareText(ValueAsString,sString)<>0then

exit;

//attributecount

ifxcAttribCountinOptionsthen

ifAttributeCount<>uteCountthen

exit;

//attributenamesandvalues

if(xcAttribNamesinOptions)or(xcAttribValuesinOptions)then

fori:=0toAttributeCount-1do

begin

Index:=uteIndexByName(AttributeName[i]);

ifIndex<0then

ifxcAttribNamesinOptionsthen

exit

else

continue;

ifxcAttribValuesinOptionsthen

ifAnsiCompareText(AttributeValue[i],uteValue[Index])<>0then

exit;

end;

//childnodecount

ifxcChildCountinOptionsthen

ifNodeCount<>untthen

exit;

//Ifwearrivehere,itmeansnodifferenceswerefound,returnTrue

NodeResult:=True;

finally

Result:=ChildResultandNodeResult;

if(notNodeResult)andassigned(MismatchNodes)then

(0,Self);

end;

end;

d(ANode:TXmlNode):integer;

begin

ifassigned(ANode)then

begin

:=Self;

Document(Document);

ifnotassigned(FNodes)then

FNodes:=;

Result:=(ANode);

endelse

Result:=-1;

end;

AttributeValue(constNodeName,AttribName,AttribValue:string;

ShouldRecurse:boolean):TXmlNode;

//Thisfunctionreturnsapointertothefirstsubnodethathasanattributewith

//nameAttribNameandvalueAttribValue.

var

i:integer;

Node:TXmlNode;

begin

Result:=nil;

//Findallnodesthatarepotentialresults

fori:=0toNodeCount-1do

begin

Node:=Nodes[i];

if(AnsiCompareText(,NodeName)=0)and

ribute(AttribName)and

(AnsiCompareText(uteByName[AttribName],AttribValue)=0)then

begin

Result:=Node;

exit;

end;

//Recursivecall

ifShouldRecursethen

Result:=AttributeValue(NodeName,AttribName,AttribValue,True);

ifassigned(Result)then

exit;

end;

end;

ElementType(ElementType:TXmlElementType):TXmlNode;

var

i:integer;

begin

Result:=nil;

fori:=0toNodeCount-1do

ifNodes[i].ElementType=ElementTypethen

begin

Result:=Nodes[i];

exit;

end;

end;

Name(constAName:string):TXmlNode;

var

i:integer;

begin

Result:=nil;

fori:=0toNodeCount-1do

ifAnsiCompareText(Nodes[i].Name,AName)=0then

begin

Result:=Nodes[i];

exit;

end;

end;

lete(Index:integer);

begin

if(Index>=0)and(Index

begin

TXmlNode(FNodes[Index]).Free;

(Index);

end;

end;

change(Index1,Index2:integer);

begin

if(Index1>=0)and(Index1

(Index2>=0)and(Index2

ge(Index1,Index2);

end;

tract(ANode:TXmlNode):TXmlNode;

var

Index:integer;

begin

//CompatibilitywithDelphi4

Result:=nil;

ifassigned(FNodes)then

begin

Index:=f(ANode);

ifIndex>=0thenbegin

Result:=ANode;

(Index);

end;

end;

end;

ndOrCreate(constAName:string):TXmlNode;

//FindthenodewithAName,andifnotfound,addnewone

begin

Result:=NodeByName(AName);

ifnotassigned(Result)then

Result:=NodeNew(AName);

end;

dexByName(constAName:string):integer;

begin

Result:=0;

whileResult

begin

ifAnsiCompareText(Nodes[Result].Name,AName)=0then

exit;

inc(Result);

end;

ifResult=NodeCountthen

Result:=-1;

end;

dexByNameFrom(constAName:string;AFrom:integer):integer;

begin

Result:=AFrom;

whileResult

begin

ifAnsiCompareText(Nodes[Result].Name,AName)=0then

exit;

inc(Result);

end;

ifResult=NodeCountthen

Result:=-1;

end;

dexOf(ANode:TXmlNode):integer;

begin

ifassigned(ANode)andassigned(FNodes)then

Result:=f(ANode)

else

Result:=-1;

end;

sert(Index:integer;ANode:TXmlNode);

//InsertthenodeANodeatlocationIndexinthelist.

begin

ifnotassigned(ANode)then

exit;

if(Index>=0)and(Index<=NodeCount)then

begin

ifnotassigned(FNodes)then

FNodes:=;

:=Self;

(Index,ANode);

end;

end;

w(constAName:string):TXmlNode;

//Addanewchildnodeandreturnitspointer

begin

Result:=Nodes[NodeAdd(Name(Document,AName))];

end;

wAtIndex(Index:integer;constAName:string):TXmlNode;

//CreateanewnodewithAName,andinsertitintothesubnodelistatlocation

//Index,andreturnapointertoit.

begin

if(Index>=0)and(Index<=NodeCount)then

begin

Result:=Name(Document,AName);

NodeInsert(Index,Result);

endelse

Result:=nil;

end;

move(ANode:TxmlNode):integer;

begin

Result:=NodeIndexOf(ANode);

ifResult>=0then

NodeDelete(Result);

end;

yName(constAName:string;constAList:TList);

//FillAListwithnodesthathavenameAName

var

i:integer;

begin

ifnotassigned(AList)then

exit;

;

fori:=0toNodeCount-1do

ifAnsiCompareText(Nodes[i].Name,AName)=0then

(Nodes[i]);

end;

lear;

var

i:integer;

begin

fori:=0toNodeCount-1do

TXmlNode(FNodes[i]).Free;

FreeAndNil(FNodes);

end;

ag(constAValue:string;TagStart,TagClose:integer);

var

LItems:TStringList;

begin

//Createalisttoholdstringitems

LItems:=;

try

ParseAttributes(AValue,TagStart,TagClose,LItems);

//Determinename,attributesorvalueforeachelementtype

caseElementTypeof

xeDeclaration:

FName:='xml';

xeStyleSheet:

begin

FName:='xml-stylesheet';

//Wealsosetthisasthevalueforusein"StyleSheetString"

ValueDirect:=trim(copy(AValue,TagStart,TagClose-TagStart));

end;

else

//Firstitemisthename-isitthere?

=0then

(sxeMissingElementName);

//Setthename-usingtheelementinsteadofpropertyforspeed

FName:=LItems[0];

(0);

end;//case

//Anyattributes?

>0then

begin

CheckCreateAttributesList;

(LItems);

end;

finally

;

end;

end;

yAsDirectNode:boolean;

//Ifthisnodequalifiesasadirectnodewhenwriting,wereturnTrue.

//Adirectnodemayhaveattributes,rmore,

//therootnodewillneverbedisplayedasadirectnode.

begin

Result:=

(Length(FValue)=0)and

(NodeCount=0)and

(ElementType=xeNormal)and

notUseFullNodesand

(TreeDepth>0);

end;

tributeBool(constAName:string;ADefault:boolean):boolean;

var

V:string;

begin

V:=AttributeByName[AName];

try

Result:=sdStringToBool(V);

except

Result:=ADefault;

end;

end;

tributeDateTime(constAName:string;

ADefault:TDateTime):TDateTime;

var

V:string;

begin

V:=AttributeByName[AName];

try

Result:=sdDateTimeFromStringDefault(V,ADefault);

except

Result:=ADefault;

end;

end;

tributeFloat(constAName:string;ADefault:double):double;

var

V:string;

Code:integer;

begin

V:=AttributeByName[AName];

val(StringReplace(V,',','.',[]),Result,Code);

ifCode>0then

Result:=ADefault;

end;

tributeInteger(constAName:string;ADefault:integer):integer;

begin

Result:=StrToIntDef(AttributeByName[AName],ADefault);

end;

tributeInt64(constAName:string;ADefault:int64):int64;

begin

Result:=StrToInt64Def(AttributeByName[AName],ADefault);

end;

tributeString(constAName:string;constADefault:string):string;

begin

Result:=AttributeByName[AName];

iflength(Result)=0then

Result:=ADefault;

end;

ol(constAName:string;ADefault:boolean):boolean;

var

Index:integer;

begin

Result:=ADefault;

Index:=NodeIndexByName(AName);

ifIndex>=0then

Result:=Nodes[Index].ValueAsBoolDef(ADefault);

end;

{$IFDEFUSEGRAPHICS}

ush(constAName:string;ABrush:TBrush);

var

Child:TXmlNode;

begin

Child:=NodeByName(AName);

ifassigned(Child)thenwithChilddo

begin

//Readvalues

:=ReadColor('Color',clWhite);

:=TBrushStyle(ReadInteger('Style',integer(bsSolid)));

endelse

begin

//Defaults

:=nil;

:=clWhite;

:=bsSolid;

end;

end;

lor(constAName:string;ADefault:TColor):TColor;

var

Index:integer;

begin

Result:=ADefault;

Index:=NodeIndexByName(AName);

ifIndex>=0then

Result:=StrToInt(Nodes[Index].ValueAsString);

end;

{$ENDIF}

teTime(constAName:string;ADefault:TDateTime):TDateTime;

//DateMUSTalwaysbewritteninthisformat:

//YYYY-MM-DD(ifjustdate)or

//YYYY-MM-DDThh:mm:(andsforuniversaltime

//elphi'sTDateTimedoesnotgiveusaclueaboutthetimezone,

//thisistheeasiestsolution)

//ThisformatSHOULDNOTbechanged,toavoidallkindsof

//conversionerrorsinfuture.

//ThisformatiscompatiblewiththeW3Cdate/timespecificationasfoundhere:

///TR/NOTE-datetime

begin

Result:=sdDateTimeFromStringDefault(ReadString(AName,''),ADefault);

end;

更多推荐

quotedstr