这两天在个朋友Yao写一个很简单而繁琐的程序--学生排座程序。说简单,是需求很简单,就是随机排座;说繁琐是在很多细节和GUI实现上累的我半死。想想,我还是喜欢写console程序。。。
    程序中的文件存储操作采用的是xml格式,以前我都使用TinyXML,一个很小,很好用的XML库。由于这次程序使用的是wxWidgets,因此XML部分也就使用wxWidgets提供的wxXmlDocument/wxXmlNode/wxXmlProperty了。这几个对象的名字在TinyXML中都有相对应的对象,上手也快,但细节上有些不同,尤其是wxXmlNodeType这个类型的使用上。
 enum wxXmlNodeType
enum wxXmlNodeType


 {
{
 // note: values are synchronized with xmlElementType from libxml
    // note: values are synchronized with xmlElementType from libxml
 wxXML_ELEMENT_NODE       =  1,
    wxXML_ELEMENT_NODE       =  1,
 wxXML_ATTRIBUTE_NODE     =  2,
    wxXML_ATTRIBUTE_NODE     =  2,
 wxXML_TEXT_NODE          =  3,
    wxXML_TEXT_NODE          =  3,
 wxXML_CDATA_SECTION_NODE =  4,
    wxXML_CDATA_SECTION_NODE =  4,
 wxXML_ENTITY_REF_NODE    =  5,
    wxXML_ENTITY_REF_NODE    =  5,
 wxXML_ENTITY_NODE        =  6,
    wxXML_ENTITY_NODE        =  6,
 wxXML_PI_NODE            =  7,
    wxXML_PI_NODE            =  7,
 wxXML_COMMENT_NODE       =  8,
    wxXML_COMMENT_NODE       =  8,
 wxXML_DOCUMENT_NODE      =  9,
    wxXML_DOCUMENT_NODE      =  9,
 wxXML_DOCUMENT_TYPE_NODE = 10,
    wxXML_DOCUMENT_TYPE_NODE = 10,
 wxXML_DOCUMENT_FRAG_NODE = 11,
    wxXML_DOCUMENT_FRAG_NODE = 11,
 wxXML_NOTATION_NODE      = 12,
    wxXML_NOTATION_NODE      = 12,
 wxXML_HTML_DOCUMENT_NODE = 13
    wxXML_HTML_DOCUMENT_NODE = 13
 };
};    下面是使用wxWidgets中XML对象的open/save操作代码,记录下。
  1 int CManageObject::Open(const wxString &file)
int CManageObject::Open(const wxString &file)
  2

 {
{
  3 wxXmlDocument doc;
    wxXmlDocument doc;
  4 if(!doc.Load(file))
    if(!doc.Load(file))
  5 return -1;
        return -1;
  6 
    
  7 wxXmlNode* root = doc.GetRoot();
    wxXmlNode* root = doc.GetRoot();
  8 if(root == NULL)
    if(root == NULL)
  9 return -1;
        return -1;
 10 wxString str = root->GetName();
    wxString str = root->GetName();
 11 if(str != wxT("RunSite"))
    if(str != wxT("RunSite"))
 12 return -1;
        return -1;
 13
 14 New();
    New();
 15
 16 wxXmlNode* si = root->GetChildren();
    wxXmlNode* si = root->GetChildren();
 17 if(si == NULL)
    if(si == NULL)
 18 return -1;
        return -1;
 19 str = si->GetName();
    str = si->GetName();
 20 if(str != wxT("SiteInfo"))
    if(str != wxT("SiteInfo"))
 21 return -1;
        return -1;
 22 wxXmlNode* col = si->GetChildren();
    wxXmlNode* col = si->GetChildren();
 23 if(col == NULL)
    if(col == NULL)
 24 return -1;
        return -1;
 25 str = col->GetName();
    str = col->GetName();
 26 if(str != wxT("Col"))
    if(str != wxT("Col"))
 27 return -1;
        return -1;
 28 str = col->GetNodeContent();
    str = col->GetNodeContent();
 29 if(!str.ToLong(&m_data.col))
    if(!str.ToLong(&m_data.col))
 30 return -1;
        return -1;
 31 wxXmlNode* row = col->GetNext();
    wxXmlNode* row = col->GetNext();
 32 if(row == NULL)
    if(row == NULL)
 33 return -1;
        return -1;
 34 str = row->GetName();
    str = row->GetName();
 35 if(str != wxT("Row"))
    if(str != wxT("Row"))
 36 return -1;
        return -1;
 37 str = row->GetNodeContent();
    str = row->GetNodeContent();
 38 if(!str.ToLong(&m_data.row))
    if(!str.ToLong(&m_data.row))
 39 return -1;
        return -1;
 40
 41 wxXmlNode* special = row->GetNext();
    wxXmlNode* special = row->GetNext();
 42 if(special != NULL)
    if(special != NULL)
 43
 
     {
{
 44 m_data.sitespecial = true;
        m_data.sitespecial = true;
 45 if(special->GetName() != wxT("Special"))
        if(special->GetName() != wxT("Special"))
 46 return -1;
            return -1;
 47 wxXmlNode* s = special->GetChildren();
        wxXmlNode* s = special->GetChildren();
 48 if(s == NULL || s->GetName() != wxT("ColRange"))
        if(s == NULL || s->GetName() != wxT("ColRange"))
 49 return -1;
            return -1;
 50 wxXmlProperty* p = s->GetProperties();
        wxXmlProperty* p = s->GetProperties();
 51 if(p == NULL || p->GetName() != wxT("begin"))
        if(p == NULL || p->GetName() != wxT("begin"))
 52 return -1;
            return -1;
 53 if(!p->GetValue().ToLong(&m_data.bcol))
        if(!p->GetValue().ToLong(&m_data.bcol))
 54 return -1;
            return -1;
 55 p = p->GetNext();
        p = p->GetNext();
 56 if(p == NULL || p->GetName() != wxT("end"))
        if(p == NULL || p->GetName() != wxT("end"))
 57 return -1;
            return -1;
 58 if(!p->GetValue().ToLong(&m_data.ecol))
        if(!p->GetValue().ToLong(&m_data.ecol))
 59 return -1;
            return -1;
 60
 61 s = s->GetNext();
        s = s->GetNext();
 62 if(s == NULL || s->GetName() != wxT("RowRange"))
        if(s == NULL || s->GetName() != wxT("RowRange"))
 63 return -1;
            return -1;
 64 p = s->GetProperties();
        p = s->GetProperties();
 65 if(p == NULL || p->GetName() != wxT("begin"))
        if(p == NULL || p->GetName() != wxT("begin"))
 66 return -1;
            return -1;
 67 if(!p->GetValue().ToLong(&m_data.brow))
        if(!p->GetValue().ToLong(&m_data.brow))
 68 return -1;
            return -1;
 69 p = p->GetNext();
        p = p->GetNext();
 70 if(p == NULL || p->GetName() != wxT("end"))
        if(p == NULL || p->GetName() != wxT("end"))
 71 return -1;
            return -1;
 72 if(!p->GetValue().ToLong(&m_data.erow))
        if(!p->GetValue().ToLong(&m_data.erow))
 73 return -1;
            return -1;
 74 }
    }
 75 else
    else
 76
 
     {
{
 77 m_data.sitespecial = false;
        m_data.sitespecial = false;
 78 }
    }
 79
 80 wxXmlNode* bi = si->GetNext();
    wxXmlNode* bi = si->GetNext();
 81 if(bi == NULL || bi->GetName() != wxT("BoxInfo"))
    if(bi == NULL || bi->GetName() != wxT("BoxInfo"))
 82 return -1;
        return -1;
 83 wxXmlNode* b = bi->GetChildren();
    wxXmlNode* b = bi->GetChildren();
 84 while(b != NULL)
    while(b != NULL)
 85
 
     {
{
 86 if(b->GetName() != wxT("Box"))
        if(b->GetName() != wxT("Box"))
 87 return -1;
            return -1;
 88 Data::box_t box;
        Data::box_t box;
 89 wxXmlProperty* p = b->GetProperties();
        wxXmlProperty* p = b->GetProperties();
 90 if(p == NULL || p->GetName() != wxT("id"))
        if(p == NULL || p->GetName() != wxT("id"))
 91 return -1;
            return -1;
 92 box.id = p->GetValue();
        box.id = p->GetValue();
 93
 94 p = p->GetNext();
        p = p->GetNext();
 95 if(p == NULL || p->GetName() != wxT("name"))
        if(p == NULL || p->GetName() != wxT("name"))
 96 return -1;
            return -1;
 97 box.name = p->GetValue();
        box.name = p->GetValue();
 98
 99 p = p->GetNext();
        p = p->GetNext();
100 if(p != NULL)
        if(p != NULL)
101
 
         {
{
102 if(p->GetName() != wxT("special"))
            if(p->GetName() != wxT("special"))
103 return -1;
                return -1;
104 if(p->GetValue() == wxT("T"))
            if(p->GetValue() == wxT("T"))
105 box.special = true;
                box.special = true;
106 else
            else
107 box.special = false;
                box.special = false;
108 }
        }
109 else
        else
110
 
         {
{
111 box.special = false;
            box.special = false;
112 }
        }
113
114 m_data.vct.push_back(box);
        m_data.vct.push_back(box);
115
116 b = b->GetNext();
        b = b->GetNext();
117 }
    }
118
119 return 0;
    return 0;
120 }
}
121
122 int CManageObject::Save(const wxString &file)
int CManageObject::Save(const wxString &file)
123

 {
{
124 wxXmlNode* cx = NULL;
    wxXmlNode* cx = NULL;
125 wxXmlNode* root = new wxXmlNode(NULL, wxXML_ELEMENT_NODE, wxT("RunSite"));
    wxXmlNode* root = new wxXmlNode(NULL, wxXML_ELEMENT_NODE, wxT("RunSite"));    
126
127 //SiteInfo
//SiteInfo
128 wxXmlNode* si = new wxXmlNode(NULL, wxXML_ELEMENT_NODE, wxT("SiteInfo"), wxEmptyString);
    wxXmlNode* si = new wxXmlNode(NULL, wxXML_ELEMENT_NODE, wxT("SiteInfo"), wxEmptyString);
129
130 wxXmlNode* col = new wxXmlNode(wxXML_ELEMENT_NODE, wxT("Col"));
    wxXmlNode* col = new wxXmlNode(wxXML_ELEMENT_NODE, wxT("Col"));
131 cx = new wxXmlNode(wxXML_TEXT_NODE, wxEmptyString, wxString::Format(wxT("%d"), m_data.col));
    cx = new wxXmlNode(wxXML_TEXT_NODE, wxEmptyString, wxString::Format(wxT("%d"), m_data.col));
132 col->AddChild(cx);
    col->AddChild(cx);
133 si->AddChild(col);
    si->AddChild(col);
134 wxXmlNode* row = new wxXmlNode(wxXML_ELEMENT_NODE, wxT("Row"));
    wxXmlNode* row = new wxXmlNode(wxXML_ELEMENT_NODE, wxT("Row"));
135 cx = new wxXmlNode(wxXML_TEXT_NODE, wxEmptyString, wxString::Format(wxT("%d"), m_data.row));
    cx = new wxXmlNode(wxXML_TEXT_NODE, wxEmptyString, wxString::Format(wxT("%d"), m_data.row));
136 row->AddChild(cx);
    row->AddChild(cx);
137 si->AddChild(row);
    si->AddChild(row);
138
139 wxXmlNode* sp = NULL;
    wxXmlNode* sp = NULL;
140
141 if(m_data.sitespecial)
    if(m_data.sitespecial)
142
 
     {
{
143 wxXmlNode* sp = new wxXmlNode(NULL, wxXML_ELEMENT_NODE, wxT("Special"));
        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));
        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);
        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);
        wxXmlNode* c = new wxXmlNode(NULL, wxXML_ELEMENT_NODE, wxT("ColRange"), wxEmptyString, b);
148 //        c->AddProperty(b);
//        c->AddProperty(b);
149 
        
150 sp->AddChild(c);
        sp->AddChild(c);
151
152 
        
153 e = new wxXmlProperty(wxT("end"), wxString::Format(wxT("%d"), m_data.erow));
        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);
        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);
        wxXmlNode* r = new wxXmlNode(NULL, wxXML_ELEMENT_NODE, wxT("RowRange"), wxEmptyString, b);
156 //        r->AddProperty(b);
//        r->AddProperty(b);
157 sp->AddChild(r);
        sp->AddChild(r);
158
159 si->AddChild(sp);
        si->AddChild(sp);
160 }
    }
161
162 root->AddChild(si);
    root->AddChild(si);
163
164 //Box Info
//Box Info
165 wxXmlNode* bi = new wxXmlNode(NULL, wxXML_ELEMENT_NODE, wxT("BoxInfo"));
    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)
    for(Data::TBoxVector::const_iterator it = m_data.vct.begin(); it != m_data.vct.end(); ++ it)
167
 
     {
{
168 wxXmlProperty* s = NULL;
        wxXmlProperty* s = NULL;
169 if(it->special)
        if(it->special)
170 s = new wxXmlProperty(wxT("special"), wxT("T"));
            s = new wxXmlProperty(wxT("special"), wxT("T"));
171
172 wxXmlProperty* n = new wxXmlProperty(wxT("name"), it->name, s);
        wxXmlProperty* n = new wxXmlProperty(wxT("name"), it->name, s);
173 wxXmlProperty* i = new wxXmlProperty(wxT("id"), it->id, n);
        wxXmlProperty* i = new wxXmlProperty(wxT("id"), it->id, n);
174 wxXmlNode* b = new wxXmlNode(NULL, wxXML_ELEMENT_NODE, wxT("Box"), wxEmptyString, i);
        wxXmlNode* b = new wxXmlNode(NULL, wxXML_ELEMENT_NODE, wxT("Box"), wxEmptyString, i);
175 //        b->AddProperty(i);
//        b->AddProperty(i);
176
177 bi->AddChild(b);
        bi->AddChild(b);
178 }
    }
179
180 root->AddChild(bi);
    root->AddChild(bi);
181
182 wxXmlDocument doc;
    wxXmlDocument doc;
183 doc.SetRoot(root);
    doc.SetRoot(root);
184 if(!doc.Save(file))
    if(!doc.Save(file))
185 return -1;
        return -1;
186
187 return 0;
    return 0;
188 }
}     边学边写,凌乱的狠,还好,想来朋友Yao不会关心代码是怎么写的,只是自己看着不舒服了~对应的XML文件如下:
 <?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
 <RunSite>
<RunSite>
 <SiteInfo>
  <SiteInfo>
 <Col>3</Col>
    <Col>3</Col>
 <Row>4</Row>
    <Row>4</Row>
 <Special>
    <Special>
 <ColRange begin="2" end="3"/>
      <ColRange begin="2" end="3"/>
 <RowRange begin="3" end="4"/>
      <RowRange begin="3" end="4"/>
 </Special>
    </Special>
 </SiteInfo>
  </SiteInfo>
 <BoxInfo>
  <BoxInfo>
 <Box id="1" name="11"/>
    <Box id="1" name="11"/>
 <Box id="2" name="22" special="T"/>
    <Box id="2" name="22" special="T"/>
 </BoxInfo>
  </BoxInfo>
 </RunSite>
</RunSite>