?
現在
,
越來越多的程序使用
xml
文件作為應用程序的配置文件
,
在
windows
平臺上
,
一般的程序使用微軟的
msxml
接口來讀寫
xml
文件
.
xml
文件原則上可以存儲任意形式的數據
,
比如象點坐標
,
顏色
rgb
值
,
矩形坐標
,
字符串
,
數值或者其他自己定義的數據結構等
.
如果
xml
需要存儲結構化的數據列
,
或者存儲在
xml
文件中的數據因為邏輯或者業務的原因存在結構上的嵌套包含關系
,
比如要存儲某個窗口的位置
,
標題
,
坐標等情況
,
還要存儲這個窗口的子窗口的相同信息
.
在情況下
,
會存在下列幾個問題
1.
應用程序配置結構和
xml
讀寫操作過于耦合
,
如果要將不同的結構寫入
xml
文件
,
需要操作
msxml
調用不同的接口
,
而一旦這些配置結構發生改變
,
將需要同時修改
xml
文件的讀寫代碼
.
對于不同的配置結構
,
就需要寫不同的
xml
讀寫操作
,
代碼重用性不高
.
2.
對于多個數據對象和有嵌套包含關系的數據結構而言
,
還需要自己實現循環語句對
xml
文件中的對象進行讀寫
.
?
本文實現了一個
xml
讀寫和自身結構無關的類模板
,
并且支持結構嵌套
,
簡化了
xml
的讀寫操作
,
需要
Loki for vc6
庫支持
.
?
如想要存儲一組
web
站點的結構
,
包括
url(string),
端口
(int),
用戶名
(string),
口令
(string)
?
可以定義下面的類結構
:
?
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
() {}
??????
};
?
配置信息存儲和加載的代碼
?
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
);
????????????? }
?????? }
}
?
??????? 可以看見,在代碼中,沒有具體的有關xml文件的讀寫操作的,涉及的只是于業務相關的數據結構的定義和存取操作,同時,在業務需求發生變化或者需要添加新的業務結構時,只需要修改業務結構定義和定義新的業務結構并將其加入節點創建工廠就可以了.
?
代碼下載
http://www.shnenglu.com/Files/hdqqq/xml_config_file.rar
?
附加說明
:
代碼中使用抽象工廠作來創建節點對象
,
對于存儲于
xml
文件中的結構
,
采用
md5
的
hash
值作為每個結構的
id.
?