?
現(xiàn)在
,
越來(lái)越多的程序使用
xml
文件作為應(yīng)用程序的配置文件
,
在
windows
平臺(tái)上
,
一般的程序使用微軟的
msxml
接口來(lái)讀寫(xiě)
xml
文件
.
xml
文件原則上可以存儲(chǔ)任意形式的數(shù)據(jù)
,
比如象點(diǎn)坐標(biāo)
,
顏色
rgb
值
,
矩形坐標(biāo)
,
字符串
,
數(shù)值或者其他自己定義的數(shù)據(jù)結(jié)構(gòu)等
.
如果
xml
需要存儲(chǔ)結(jié)構(gòu)化的數(shù)據(jù)列
,
或者存儲(chǔ)在
xml
文件中的數(shù)據(jù)因?yàn)檫壿嫽蛘邩I(yè)務(wù)的原因存在結(jié)構(gòu)上的嵌套包含關(guān)系
,
比如要存儲(chǔ)某個(gè)窗口的位置
,
標(biāo)題
,
坐標(biāo)等情況
,
還要存儲(chǔ)這個(gè)窗口的子窗口的相同信息
.
在情況下
,
會(huì)存在下列幾個(gè)問(wèn)題
1.
應(yīng)用程序配置結(jié)構(gòu)和
xml
讀寫(xiě)操作過(guò)于耦合
,
如果要將不同的結(jié)構(gòu)寫(xiě)入
xml
文件
,
需要操作
msxml
調(diào)用不同的接口
,
而一旦這些配置結(jié)構(gòu)發(fā)生改變
,
將需要同時(shí)修改
xml
文件的讀寫(xiě)代碼
.
對(duì)于不同的配置結(jié)構(gòu)
,
就需要寫(xiě)不同的
xml
讀寫(xiě)操作
,
代碼重用性不高
.
2.
對(duì)于多個(gè)數(shù)據(jù)對(duì)象和有嵌套包含關(guān)系的數(shù)據(jù)結(jié)構(gòu)而言
,
還需要自己實(shí)現(xiàn)循環(huán)語(yǔ)句對(duì)
xml
文件中的對(duì)象進(jìn)行讀寫(xiě)
.
?
本文實(shí)現(xiàn)了一個(gè)
xml
讀寫(xiě)和自身結(jié)構(gòu)無(wú)關(guān)的類模板
,
并且支持結(jié)構(gòu)嵌套
,
簡(jiǎn)化了
xml
的讀寫(xiě)操作
,
需要
Loki for vc6
庫(kù)支持
.
?
如想要存儲(chǔ)一組
web
站點(diǎn)的結(jié)構(gòu)
,
包括
url(string),
端口
(int),
用戶名
(string),
口令
(string)
?
可以定義下面的類結(jié)構(gòu)
:
?
class
__app_config
:
public
Xml_Attribute_List
<TYPELIST_1(
XML_ATTR_NULLTYPE
)>
{
public
:
??????
__app_config
() {
?????????????
SetTagName
(
_T
(
"AppConfig"
));
?????? }
?????? ~
__app_config
() {}
};
?
typedef
Xml_Config_Node
<
__app_config
>
AppConfigRoot
;
?
class
__site_info
:
public
Xml_Attribute_List
<TYPELIST_4(
XML_ATTR_CSTRING
,
XML_ATTR_INT
,
XML_ATTR_CSTRING
,
XML_ATTR_CSTRING
)>
{
public
:
??????
__site_info
() {
?????????????
SetTagName
(
_T
(
"WebSite"
));
?????????????
SetAttributeName
(
_T
(
"url"
),
_T
(
"port"
),
_T
(
"username"
),
_T
(
"password"
));
?????? }
?????? ~
__site_info
() {}
?
??????
GET_SET_ATTR4
(
url
,
port
,username,password, TYPELIST_4(
XML_ATTR_CSTRING
,
XML_ATTR_INT
,
XML_ATTR_CSTRING
,
XML_ATTR_CSTRING
))
?
};
?
typedef
Xml_Config_Node
<
__site_info
>
WebSiteInfoNode
;
?
?
typedef
XmlConfigNodeFactory
<TYPELIST_2(
AppConfigRoot
,
WebSiteInfoNode
)>
NodeCreateFactory
;
?
typedef
XmlConfigFile
<
AppConfigRoot
,
NodeCreateFactory
>
AppConfigFileBase
;
?
class
AppConfigFile
:
public
AppConfigFileBase
{
public
:
??????
void
AddSiteInfo
(
LPCTSTR
url
,
int
port
,
LPCTSTR
user
,
LPCTSTR
pwd
) {
?????????????
WebSiteInfoNode
*
pnode
=
new
WebSiteInfoNode
;
?????????????
pnode
->
GetAttribute
().Set_url(
url
);
?????????????
pnode
->
GetAttribute
().
Set_port
(
port
);
?????????????
pnode
->
GetAttribute
().
Set_username
(
user
);
?????????????
pnode
->
GetAttribute
().
Set_password
(
pwd
);
?????????????
GetRoot
().
AddChildNode
(
pnode
);
?
?????? }
?
??????
int
GetSiteInfoCount
() {
?????????????
return
GetRoot
().
GetChildCount
();
?????? }
?
??????
WebSiteInfoNode
*
GetSiteInfo
(
int
index
) {
?????????????
Xml_NodeData_Base
*
pbase
=
GetRoot
().
GetChildNode
(
index
);
?????????????
if
(
pbase
) {
????????????????????
WebSiteInfoNode
*
pnode
= (
WebSiteInfoNode
*)
pbase
;
????????????????????
return
pnode
;
????????????? }
else
{
????????????????????
return
NULL
;
????????????? }
?????? }
?
public
:
??????
AppConfigFile
() {}
?????? ~
AppConfigFile
() {}
??????
};
?
配置信息存儲(chǔ)和加載的代碼
?
void
SaveConfig
()
{
??????
AppConfigFile
lconfigfile
;
??????
lconfigfile
.
AddSiteInfo
(
"192.168.0.1"
,
80
,
"guest"
,
"hello"
);
??????
lconfigfile
.
AddSiteInfo
(
"192.168.0.2"
,
80
,
"guest"
,
"hello"
);
??????
lconfigfile
.
AddSiteInfo
(
"192.168.0.3"
,
80
,
"guest"
,
"hello"
);
??????
lconfigfile
.
AddSiteInfo
(
"192.168.0.4"
,
80
,
"test"
,
"hi"
);
??????
lconfigfile
.
SaveToXmlFile
(
"c:\\test.xml"
);
}
?
void
output_config
(
WebSiteInfoNode
*
pnode
)
{
??????
if
(
pnode
) {
?????????????
cout
<< (
LPCTSTR
)
pnode
->
GetAttribute
().Get_url() <<
"? "
;
?????????????
cout
<<
pnode
->
GetAttribute
().
Get_port
() <<
" "
;
?????????????
cout
<< (
LPCTSTR
)
pnode
->
GetAttribute
().
Get_username
() <<
" "
;
?????????????
cout
<< (
LPCTSTR
)
pnode
->
GetAttribute
().
Get_password
() <<
endl
;
?????? }
}
?
void
LoadConfig
()
{
??????
AppConfigFile
lconfigfile
;
??????
lconfigfile
.
LoadFromXmlFile
(
"c:\\test.xml"
);
??????
int
i
,
count
;
??????
count
=
lconfigfile
.
GetSiteInfoCount
();
??????
if
(
count
>
0
) {
?????????????
for
(
i
=
0
;
i
<
count
;
i
++) {
????????????????????
WebSiteInfoNode
*
pnode
=
lconfigfile
.
GetSiteInfo
(
i
);
????????????????????
output_config
(
pnode
);
????????????? }
?????? }
}
?
??????? 可以看見(jiàn),在代碼中,沒(méi)有具體的有關(guān)xml文件的讀寫(xiě)操作的,涉及的只是于業(yè)務(wù)相關(guān)的數(shù)據(jù)結(jié)構(gòu)的定義和存取操作,同時(shí),在業(yè)務(wù)需求發(fā)生變化或者需要添加新的業(yè)務(wù)結(jié)構(gòu)時(shí),只需要修改業(yè)務(wù)結(jié)構(gòu)定義和定義新的業(yè)務(wù)結(jié)構(gòu)并將其加入節(jié)點(diǎn)創(chuàng)建工廠就可以了.
?
代碼下載
http://www.shnenglu.com/Files/hdqqq/xml_config_file.rar
?
附加說(shuō)明
:
代碼中使用抽象工廠作來(lái)創(chuàng)建節(jié)點(diǎn)對(duì)象
,
對(duì)于存儲(chǔ)于
xml
文件中的結(jié)構(gòu)
,
采用
md5
的
hash
值作為每個(gè)結(jié)構(gòu)的
id.
?