记录:wxXmlNode的使用
这两天在个朋友Yao写一个很简单而繁琐的程序--学生排座程序。说简单,是需求很简单,就是随机排座;说繁琐是在很多细节和GUI实现上累的我半死。想想,我还是喜欢写console程序。。。
程序中的文件存储操作采用的是xml格式,以前我都使用TinyXML,一个很小,很好用的XML库。由于这次程序使用的是wxWidgets,因此XML部分也就使用wxWidgets提供的wxXmlDocument/wxXmlNode/wxXmlProperty了。这几个对象的名字在TinyXML中都有相对应的对象,上手也快,但细节上有些不同,尤其是wxXmlNodeType这个类型的使用上。
enum
wxXmlNodeType
{
// note: values are synchronized with xmlElementType from libxml
wxXML_ELEMENT_NODE = 1,
wxXML_ATTRIBUTE_NODE = 2,
wxXML_TEXT_NODE = 3,
wxXML_CDATA_SECTION_NODE = 4,
wxXML_ENTITY_REF_NODE = 5,
wxXML_ENTITY_NODE = 6,
wxXML_PI_NODE = 7,
wxXML_COMMENT_NODE = 8,
wxXML_DOCUMENT_NODE = 9,
wxXML_DOCUMENT_TYPE_NODE = 10,
wxXML_DOCUMENT_FRAG_NODE = 11,
wxXML_NOTATION_NODE = 12,
wxXML_HTML_DOCUMENT_NODE = 13
} ;
{
// note: values are synchronized with xmlElementType from libxml
wxXML_ELEMENT_NODE = 1,
wxXML_ATTRIBUTE_NODE = 2,
wxXML_TEXT_NODE = 3,
wxXML_CDATA_SECTION_NODE = 4,
wxXML_ENTITY_REF_NODE = 5,
wxXML_ENTITY_NODE = 6,
wxXML_PI_NODE = 7,
wxXML_COMMENT_NODE = 8,
wxXML_DOCUMENT_NODE = 9,
wxXML_DOCUMENT_TYPE_NODE = 10,
wxXML_DOCUMENT_FRAG_NODE = 11,
wxXML_NOTATION_NODE = 12,
wxXML_HTML_DOCUMENT_NODE = 13
} ;
下面是使用wxWidgets中XML对象的open/save操作代码,记录下。
1
int
CManageObject::Open(
const
wxString
&
file)
2 {
3 wxXmlDocument doc;
4 if(!doc.Load(file))
5 return -1;
6
7 wxXmlNode* root = doc.GetRoot();
8 if(root == NULL)
9 return -1;
10 wxString str = root->GetName();
11 if(str != wxT("RunSite"))
12 return -1;
13
14 New();
15
16 wxXmlNode* si = root->GetChildren();
17 if(si == NULL)
18 return -1;
19 str = si->GetName();
20 if(str != wxT("SiteInfo"))
21 return -1;
22 wxXmlNode* col = si->GetChildren();
23 if(col == NULL)
24 return -1;
25 str = col->GetName();
26 if(str != wxT("Col"))
27 return -1;
28 str = col->GetNodeContent();
29 if(!str.ToLong(&m_data.col))
30 return -1;
31 wxXmlNode* row = col->GetNext();
32 if(row == NULL)
33 return -1;
34 str = row->GetName();
35 if(str != wxT("Row"))
36 return -1;
37 str = row->GetNodeContent();
38 if(!str.ToLong(&m_data.row))
39 return -1;
40
41 wxXmlNode* special = row->GetNext();
42 if(special != NULL)
43 {
44 m_data.sitespecial = true;
45 if(special->GetName() != wxT("Special"))
46 return -1;
47 wxXmlNode* s = special->GetChildren();
48 if(s == NULL || s->GetName() != wxT("ColRange"))
49 return -1;
50 wxXmlProperty* p = s->GetProperties();
51 if(p == NULL || p->GetName() != wxT("begin"))
52 return -1;
53 if(!p->GetValue().ToLong(&m_data.bcol))
54 return -1;
55 p = p->GetNext();
56 if(p == NULL || p->GetName() != wxT("end"))
57 return -1;
58 if(!p->GetValue().ToLong(&m_data.ecol))
59 return -1;
60
61 s = s->GetNext();
62 if(s == NULL || s->GetName() != wxT("RowRange"))
63 return -1;
64 p = s->GetProperties();
65 if(p == NULL || p->GetName() != wxT("begin"))
66 return -1;
67 if(!p->GetValue().ToLong(&m_data.brow))
68 return -1;
69 p = p->GetNext();
70 if(p == NULL || p->GetName() != wxT("end"))
71 return -1;
72 if(!p->GetValue().ToLong(&m_data.erow))
73 return -1;
74 }
75 else
76 {
77 m_data.sitespecial = false;
78 }
79
80 wxXmlNode* bi = si->GetNext();
81 if(bi == NULL || bi->GetName() != wxT("BoxInfo"))
82 return -1;
83 wxXmlNode* b = bi->GetChildren();
84 while(b != NULL)
85 {
86 if(b->GetName() != wxT("Box"))
87 return -1;
88 Data::box_t box;
89 wxXmlProperty* p = b->GetProperties();
90 if(p == NULL || p->GetName() != wxT("id"))
91 return -1;
92 box.id = p->GetValue();
93
94 p = p->GetNext();
95 if(p == NULL || p->GetName() != wxT("name"))
96 return -1;
97 box.name = p->GetValue();
98
99 p = p->GetNext();
100 if(p != NULL)
101 {
102 if(p->GetName() != wxT("special"))
103 return -1;
104 if(p->GetValue() == wxT("T"))
105 box.special = true;
106 else
107 box.special = false;
108 }
109 else
110 {
111 box.special = false;
112 }
113
114 m_data.vct.push_back(box);
115
116 b = b->GetNext();
117 }
118
119 return 0;
120}
121
122 int CManageObject::Save( const wxString & file)
123 {
124 wxXmlNode* cx = NULL;
125 wxXmlNode* root = new wxXmlNode(NULL, wxXML_ELEMENT_NODE, wxT("RunSite"));
126
127//SiteInfo
128 wxXmlNode* si = new wxXmlNode(NULL, wxXML_ELEMENT_NODE, wxT("SiteInfo"), wxEmptyString);
129
130 wxXmlNode* col = new wxXmlNode(wxXML_ELEMENT_NODE, wxT("Col"));
131 cx = new wxXmlNode(wxXML_TEXT_NODE, wxEmptyString, wxString::Format(wxT("%d"), m_data.col));
132 col->AddChild(cx);
133 si->AddChild(col);
134 wxXmlNode* row = new wxXmlNode(wxXML_ELEMENT_NODE, wxT("Row"));
135 cx = new wxXmlNode(wxXML_TEXT_NODE, wxEmptyString, wxString::Format(wxT("%d"), m_data.row));
136 row->AddChild(cx);
137 si->AddChild(row);
138
139 wxXmlNode* sp = NULL;
140
141 if(m_data.sitespecial)
142 {
143 wxXmlNode* sp = new wxXmlNode(NULL, wxXML_ELEMENT_NODE, wxT("Special"));
144
145 wxXmlProperty* e = new wxXmlProperty(wxT("end"), wxString::Format(wxT("%d"), m_data.ecol));
146 wxXmlProperty* b = new wxXmlProperty(wxT("begin"), wxString::Format(wxT("%d"), m_data.bcol), e);
147 wxXmlNode* c = new wxXmlNode(NULL, wxXML_ELEMENT_NODE, wxT("ColRange"), wxEmptyString, b);
148// c->AddProperty(b);
149
150 sp->AddChild(c);
151
152
153 e = new wxXmlProperty(wxT("end"), wxString::Format(wxT("%d"), m_data.erow));
154 b = new wxXmlProperty(wxT("begin"), wxString::Format(wxT("%d"), m_data.brow), e);
155 wxXmlNode* r = new wxXmlNode(NULL, wxXML_ELEMENT_NODE, wxT("RowRange"), wxEmptyString, b);
156// r->AddProperty(b);
157 sp->AddChild(r);
158
159 si->AddChild(sp);
160 }
161
162 root->AddChild(si);
163
164//Box Info
165 wxXmlNode* bi = new wxXmlNode(NULL, wxXML_ELEMENT_NODE, wxT("BoxInfo"));
166 for(Data::TBoxVector::const_iterator it = m_data.vct.begin(); it != m_data.vct.end(); ++ it)
167 {
168 wxXmlProperty* s = NULL;
169 if(it->special)
170 s = new wxXmlProperty(wxT("special"), wxT("T"));
171
172 wxXmlProperty* n = new wxXmlProperty(wxT("name"), it->name, s);
173 wxXmlProperty* i = new wxXmlProperty(wxT("id"), it->id, n);
174 wxXmlNode* b = new wxXmlNode(NULL, wxXML_ELEMENT_NODE, wxT("Box"), wxEmptyString, i);
175// b->AddProperty(i);
176
177 bi->AddChild(b);
178 }
179
180 root->AddChild(bi);
181
182 wxXmlDocument doc;
183 doc.SetRoot(root);
184 if(!doc.Save(file))
185 return -1;
186
187 return 0;
188}
2 {
3 wxXmlDocument doc;
4 if(!doc.Load(file))
5 return -1;
6
7 wxXmlNode* root = doc.GetRoot();
8 if(root == NULL)
9 return -1;
10 wxString str = root->GetName();
11 if(str != wxT("RunSite"))
12 return -1;
13
14 New();
15
16 wxXmlNode* si = root->GetChildren();
17 if(si == NULL)
18 return -1;
19 str = si->GetName();
20 if(str != wxT("SiteInfo"))
21 return -1;
22 wxXmlNode* col = si->GetChildren();
23 if(col == NULL)
24 return -1;
25 str = col->GetName();
26 if(str != wxT("Col"))
27 return -1;
28 str = col->GetNodeContent();
29 if(!str.ToLong(&m_data.col))
30 return -1;
31 wxXmlNode* row = col->GetNext();
32 if(row == NULL)
33 return -1;
34 str = row->GetName();
35 if(str != wxT("Row"))
36 return -1;
37 str = row->GetNodeContent();
38 if(!str.ToLong(&m_data.row))
39 return -1;
40
41 wxXmlNode* special = row->GetNext();
42 if(special != NULL)
43 {
44 m_data.sitespecial = true;
45 if(special->GetName() != wxT("Special"))
46 return -1;
47 wxXmlNode* s = special->GetChildren();
48 if(s == NULL || s->GetName() != wxT("ColRange"))
49 return -1;
50 wxXmlProperty* p = s->GetProperties();
51 if(p == NULL || p->GetName() != wxT("begin"))
52 return -1;
53 if(!p->GetValue().ToLong(&m_data.bcol))
54 return -1;
55 p = p->GetNext();
56 if(p == NULL || p->GetName() != wxT("end"))
57 return -1;
58 if(!p->GetValue().ToLong(&m_data.ecol))
59 return -1;
60
61 s = s->GetNext();
62 if(s == NULL || s->GetName() != wxT("RowRange"))
63 return -1;
64 p = s->GetProperties();
65 if(p == NULL || p->GetName() != wxT("begin"))
66 return -1;
67 if(!p->GetValue().ToLong(&m_data.brow))
68 return -1;
69 p = p->GetNext();
70 if(p == NULL || p->GetName() != wxT("end"))
71 return -1;
72 if(!p->GetValue().ToLong(&m_data.erow))
73 return -1;
74 }
75 else
76 {
77 m_data.sitespecial = false;
78 }
79
80 wxXmlNode* bi = si->GetNext();
81 if(bi == NULL || bi->GetName() != wxT("BoxInfo"))
82 return -1;
83 wxXmlNode* b = bi->GetChildren();
84 while(b != NULL)
85 {
86 if(b->GetName() != wxT("Box"))
87 return -1;
88 Data::box_t box;
89 wxXmlProperty* p = b->GetProperties();
90 if(p == NULL || p->GetName() != wxT("id"))
91 return -1;
92 box.id = p->GetValue();
93
94 p = p->GetNext();
95 if(p == NULL || p->GetName() != wxT("name"))
96 return -1;
97 box.name = p->GetValue();
98
99 p = p->GetNext();
100 if(p != NULL)
101 {
102 if(p->GetName() != wxT("special"))
103 return -1;
104 if(p->GetValue() == wxT("T"))
105 box.special = true;
106 else
107 box.special = false;
108 }
109 else
110 {
111 box.special = false;
112 }
113
114 m_data.vct.push_back(box);
115
116 b = b->GetNext();
117 }
118
119 return 0;
120}
121
122 int CManageObject::Save( const wxString & file)
123 {
124 wxXmlNode* cx = NULL;
125 wxXmlNode* root = new wxXmlNode(NULL, wxXML_ELEMENT_NODE, wxT("RunSite"));
126
127//SiteInfo
128 wxXmlNode* si = new wxXmlNode(NULL, wxXML_ELEMENT_NODE, wxT("SiteInfo"), wxEmptyString);
129
130 wxXmlNode* col = new wxXmlNode(wxXML_ELEMENT_NODE, wxT("Col"));
131 cx = new wxXmlNode(wxXML_TEXT_NODE, wxEmptyString, wxString::Format(wxT("%d"), m_data.col));
132 col->AddChild(cx);
133 si->AddChild(col);
134 wxXmlNode* row = new wxXmlNode(wxXML_ELEMENT_NODE, wxT("Row"));
135 cx = new wxXmlNode(wxXML_TEXT_NODE, wxEmptyString, wxString::Format(wxT("%d"), m_data.row));
136 row->AddChild(cx);
137 si->AddChild(row);
138
139 wxXmlNode* sp = NULL;
140
141 if(m_data.sitespecial)
142 {
143 wxXmlNode* sp = new wxXmlNode(NULL, wxXML_ELEMENT_NODE, wxT("Special"));
144
145 wxXmlProperty* e = new wxXmlProperty(wxT("end"), wxString::Format(wxT("%d"), m_data.ecol));
146 wxXmlProperty* b = new wxXmlProperty(wxT("begin"), wxString::Format(wxT("%d"), m_data.bcol), e);
147 wxXmlNode* c = new wxXmlNode(NULL, wxXML_ELEMENT_NODE, wxT("ColRange"), wxEmptyString, b);
148// c->AddProperty(b);
149
150 sp->AddChild(c);
151
152
153 e = new wxXmlProperty(wxT("end"), wxString::Format(wxT("%d"), m_data.erow));
154 b = new wxXmlProperty(wxT("begin"), wxString::Format(wxT("%d"), m_data.brow), e);
155 wxXmlNode* r = new wxXmlNode(NULL, wxXML_ELEMENT_NODE, wxT("RowRange"), wxEmptyString, b);
156// r->AddProperty(b);
157 sp->AddChild(r);
158
159 si->AddChild(sp);
160 }
161
162 root->AddChild(si);
163
164//Box Info
165 wxXmlNode* bi = new wxXmlNode(NULL, wxXML_ELEMENT_NODE, wxT("BoxInfo"));
166 for(Data::TBoxVector::const_iterator it = m_data.vct.begin(); it != m_data.vct.end(); ++ it)
167 {
168 wxXmlProperty* s = NULL;
169 if(it->special)
170 s = new wxXmlProperty(wxT("special"), wxT("T"));
171
172 wxXmlProperty* n = new wxXmlProperty(wxT("name"), it->name, s);
173 wxXmlProperty* i = new wxXmlProperty(wxT("id"), it->id, n);
174 wxXmlNode* b = new wxXmlNode(NULL, wxXML_ELEMENT_NODE, wxT("Box"), wxEmptyString, i);
175// b->AddProperty(i);
176
177 bi->AddChild(b);
178 }
179
180 root->AddChild(bi);
181
182 wxXmlDocument doc;
183 doc.SetRoot(root);
184 if(!doc.Save(file))
185 return -1;
186
187 return 0;
188}
边学边写,凌乱的狠,还好,想来朋友Yao不会关心代码是怎么写的,只是自己看着不舒服了~对应的XML文件如下:
<?
xml version="1.0" encoding="utf-8"
?>
< RunSite >
< SiteInfo >
< Col > 3 </ Col >
< Row > 4 </ Row >
< Special >
< ColRange begin ="2" end ="3" />
< RowRange begin ="3" end ="4" />
</ Special >
</ SiteInfo >
< BoxInfo >
< Box id ="1" name ="11" />
< Box id ="2" name ="22" special ="T" />
</ BoxInfo >
</ RunSite >
< RunSite >
< SiteInfo >
< Col > 3 </ Col >
< Row > 4 </ Row >
< Special >
< ColRange begin ="2" end ="3" />
< RowRange begin ="3" end ="4" />
</ Special >
</ SiteInfo >
< BoxInfo >
< Box id ="1" name ="11" />
< Box id ="2" name ="22" special ="T" />
</ BoxInfo >
</ RunSite >