本文是使用rapidxml序列化对象的例子
源代码源于Glooey GUI库
我使用rapidxml置换了其tinyxml并修改了很多原文的错误
devc++,vc9皆可编译 ,vc7,vc8不知道能否编译过去
1.例子如下:
#include <stdio.h>
#include <stdlib.h>
#include "XMLOutputArchive.h"
#include "XMLInputArchive.h"
#define LOAD_XML
#define XML_FILE "xml.xml"
struct Point
{
int x_;
int y_;
template<typename Archive>
void Serialize(Archive& archive)
{
archive & TAGGED_OBJECT(x) & TAGGED_OBJECT(y);
}
};
REGISTER_CLASS(Point)
struct Color
{
float red_,green_,blue_,alpha_;
template<typename Archive>
void Serialize(Archive& archive)
{
archive &TAGGED_OBJECT(red)
&TAGGED_OBJECT(green)
&TAGGED_OBJECT(blue)
&TAGGED_OBJECT(alpha);
}
};
struct Person
{
engine_string name_;
int age_;
Person():name_("XXX"),age_(-1){}
template<typename Archive>
void Serialize(Archive& archive)
{
archive &TAGGED_OBJECT(name)
&TAGGED_OBJECT(age);
}
};
REGISTER_CLASS(Color)
REGISTER_CLASS(Person)
struct Rect
{
Point from_,to_;
template<typename Archive>
void Serialize(Archive& anArchive)
{
anArchive & TAGGED_OBJECT(from) & TAGGED_OBJECT(to);
}
};
REGISTER_CLASS(Rect)
int main()
{
Point point;
std::pair<int,int> p_(-1,-2);
Rect rect;
Color color;
Person person;
#ifndef LOAD_XML
point.x_ = 1;
point.y_= 2;
p_.first = 3;
p_.second = 4;
rect.from_.x_ = 1;
rect.from_.y_ = 2;
rect.to_.x_ = 3;
rect.to_.y_ = 4;
color.red_ = 1.0f;
color.blue_ = 0.2f;
color.green_ = 0.4f;
color.alpha_ = 0.1f;
person.name_ = "娃娃";
person.age_ = 1;
XMLOutputArchive xml;
xml &ObjectNamer<Point>("point",point)
&ObjectNamer<std::pair<int,int> >("pair",p_)
&ObjectNamer<Point>("size",point)
&ObjectNamer<Color>("color",color)
&ObjectNamer<Rect>("rect",rect)
&ObjectNamer<Person>("preson",person);
xml.Save(XML_FILE);
#else
XMLInputArchive archive(XML_FILE);
archive &ObjectNamer<Rect>("rect",rect);
std::cout<<rect.from_.x_<<" "<<rect.from_.y_<<" "<<rect.to_.x_<<" "<<rect.to_.y_<<std::endl;
archive &ObjectNamer<std::pair<int,int> >("pair",p_);
std::cout<<p_.first<<" "<<p_.second<<std::endl;
archive &ObjectNamer<Color>("color",color);
std::cout<<"color "<<color.red_<<" "<<color.blue_<<" "<<color.green_<<" "<<color.alpha_<<std::endl;
archive &ObjectNamer<Person>("preson",person);
std::cout<<person.name_<<" "<<person.age_<<std::endl;
#endif
system("pause");
return 0;
}
2.相关代码()
序列化和反序列化
////////////////////////////////////////////////////////////
/// XML序列化档案
////////////////////////////////////////////////////////////
class XMLOutputArchive
{
public:
////////////////////////////////////////////////////////
/// XML序列化档案构造和析构
////////////////////////////////////////////////////////
XMLOutputArchive();
virtual ~XMLOutputArchive();
public:
////////////////////////////////////////////////////////
/// XML对象序列化
////////////////////////////////////////////////////////
template<typename T>
XMLOutputArchive& operator&(const ObjectNamer<T>& object)
{
current_node->append_node(doc.allocate_node(rapidxml::node_element,doc.allocate_string(object.GetName().c_str())));
rapidxml::xml_node<>* node = current_node;
current_node = current_node->last_node();
Write(object.GetObject());
current_node = node;
return *this;
}
////////////////////////////////////////////////////////
/// XML文件保存
////////////////////////////////////////////////////////
void Save(const engine_string& xml);
private:
////////////////////////////////////////////////////////
/// 对象序列化
////////////////////////////////////////////////////////
template<typename T>
void Write(T& object)
{
object.Serialize(*this);
}
////////////////////////////////////////////////////////
/// 指针对象序列化
////////////////////////////////////////////////////////
template<typename T>
void Write(T*& object)
{
if(object != 0)
{
FactoryInterface* factory = FactoryInterface::GetFactoryByClassName(typeid(*object).name());
factory->Serialize(typeid(*this).name(),(void*)(this),(void*&)(object));
}
}
////////////////////////////////////////////////////////
/// stl容器序列化
////////////////////////////////////////////////////////
template<typename T>
void Write(std::vector<T>& container){WriteContainer(container);}
template<typename T>
void Write(std::list<T>& container){WriteContainer(container);}
template<typename T>
void Write(std::deque<T>& container){WriteContainer(container);}
template<typename T1,typename T2>
void Write(std::map<T1, T2>& container){writeContainer(container);}
template<typename T1,typename T2>
void Write(std::pair<T1, T2>& _pair)
{
rapidxml::xml_node<>* node = current_node;
current_node = doc.allocate_node(rapidxml::node_element,"first");
node->append_node(current_node);
Write(_pair.first);
node = current_node;
current_node = doc.allocate_node(rapidxml::node_element,"second");
node->parent()->append_node(current_node);
current_node = node->parent();
current_node = current_node->last_node("second");
Write(_pair.second);
current_node = node->parent()->parent();
}
////////////////////////////////////////////////////////
/// 序列化POD数据
////////////////////////////////////////////////////////
void Write(char data);
void Write(unsigned char data);
void Write(int data);
void Write(unsigned int data);
void Write(bool data);
void Write(float data);
void Write(double data);
void Write(const engine_string& data);
void Write(engine_string& data);
////////////////////////////////////////////////////////
/// 序列化stl风格容器对象
////////////////////////////////////////////////////////
template<typename Container>
void WriteContainer(Container& container)
{
rapidxml::xml_node<>* node = current_node;
for(typename Container::iterator it = container.begin(); it != container.end(); ++it)
{
rapidxml::xml_node<>* element = doc.allocate_node(rapidxml::node_element,"item");
node->append_node(element);
current_node = node->last_node();
Write(*it);
}
current_node = node;
}
template<typename T>
void PolymorphicWrite(T*& object)
{
object->Serialize(*this);
}
rapidxml::xml_document<> doc;
rapidxml::xml_node<>* current_node;
};
3。
////////////////////////////////////////////////////////////
/// XML反序列化档案
////////////////////////////////////////////////////////////
class XMLInputArchive
{
public:
////////////////////////////////////////////////////////
/// 构造和析构XML反序列化档案
////////////////////////////////////////////////////////
XMLInputArchive(const engine_string& xml);
~XMLInputArchive();
public:
////////////////////////////////////////////////////////
/// 序列化接口
////////////////////////////////////////////////////////
template<typename T>
XMLInputArchive& operator&(const ObjectNamer<T>& object);
private:
////////////////////////////////////////////////////////
/// 反序列化一个泛型对象
////////////////////////////////////////////////////////
template<typename T>
void Read(T& object){object.Serialize(*this);}
////////////////////////////////////////////////////////
/// 反序列化一个泛型对象指针
////////////////////////////////////////////////////////
template<typename T>
void Read(T*& object);
////////////////////////////////////////////////////////
/// 反序列化stl容器
////////////////////////////////////////////////////////
template<typename T>
void Read(std::vector<T>& container){ReadContainer(container);}
template<typename T>
void Read(std::list<T>& container){ReadContainer(container);}
template<typename T>
void Read(std::deque<T>& container){ReadContainer(container);}
template<typename T1, typename T2>
void Read(std::map<T1, T2>& container){ReadContainer(container);}
template<typename T1, typename T2>
void Read(std::pair<T1, T2>& node);
////////////////////////////////////////////////////////
/// 反序列化POD数据
////////////////////////////////////////////////////////
void Read(char& data);
void Read(unsigned char& data);
void Read(int& anInteger);
void Read(unsigned int& data);
void Read(bool& boolean);
void Read(float& data);
void Read(double& data);
void Read(engine_string& string);
template<typename T>
void ReadPrimitive(T& data)
{
rapidxml::xml_node<>* node = current_node->first_node();
if(node != NULL)
{
data = string_cast<T>(node->value());
}
}
////////////////////////////////////////////////////////
/// 反序列化stl容器
////////////////////////////////////////////////////////
template<typename Container>
void ReadContainer(Container& container);
void DetermineClassName(rapidxml::xml_node<>* element);
rapidxml::xml_document<> doc;
rapidxml::xml_node<>* current_node;
engine_string classname;
};
x相关的例子代码在这里:
/Files/gaimor/archive.zip附注:做这个是因为我要重新做一个游戏GUI库