XML序列化数据对象(二)
2013-07-27 09:03
267 查看
XML序列化数据对象(二) --- 原理和构思
根标签: ObjectSerialization
第2级标签: 变量名 例如m_nA
标签的内容: 变量值 例如标签m_nA的内容是5, 那么变量m_nA的值就是5
标签属性:
class: 变量的类型(类名), 例如 int, double, IntVector
class的值有: int, double, long, char, std::string, 使用typedef定义的类型, 使用typedef定义的stl容器类型(std::vector, std::map, std::list, std::set)
使用XML序列化变量过程就是写入XML过程, 反序列化过程就是读取XML过程.
(每一个XML解析器的调用流程可能有区别).
现在有
int m_nA = 0;
int m_nB = 1;
和
struct CTest
{
double m_dC;
double m_dD;
};
CTest m_test;
// 序列化/反序列化的伪代码
Write_int();
Write_double();
Write_m_nA()
{
Write_int(m_nA);
}
Write_m_nB()
{
Write_int(m_nB);
}
Write_CTest()
{
Write_double(m_dC);
Write_double(m_dD);
}
struct CTest
{
double m_dC;
int m_nD;
};
// 伪代码
Write_CTest()
{
Write_double(m_dC);
Write_int(m_nD);
}
变量类型结构的变化, 序列化/反序列化的代码也会跟需要变化, 这种变化在一些复杂的数据机构中, 代码修改起来是很繁琐和重复的, 很容易出错. 但是这种变化又是有规律的. 既然有规律, 就可以用代码写一个程序去固定它和规范它.
在MFC中就是使用宏来把这种变化规律来固定的.
在boost中是使用模板和宏来把这种变化规律来固定的.
我这里则写了一个程序自动生成变量的序列化/反序列化代码来固定.
也就是说变量的类型结构变化了, 程序将根据类型结构的变化自动生成该变量的序列化/反序列化的代码.
(这里说的非常绕口啊)
概括说一句就是: 我写一个小程序, 该小程序能根据变量的类型结构自动生成变量的序列化/反序列化的代码.
(就是用代码来写代码, 或者说在代码之上写代码, 这个程序就是一个代码生成器).
A. 变量名.
B. 变量类型的结构
C. XML的操作代码.
有了这3类信息, 即可自动生成变量的序列化/反序列化代码.
其中B.变量类型的结构
所以变量类型的结构分类有:
A. 基本类型: char, int, double, long, float, std::string (我这里把std::string作为基本类型, 也就是字符, 因为我std::string使用的非常多).
B. struct和class: 也就是结构体和类, 结构体和类的成员层层下去, 最终也是基本类型.
C. typedef定义的类型: typedef定义A和typedef定义B, 最终也是基本类型.
D. stl定义的容器: 有std::vector, std::list; std::map; std::set(我用得最多也就这几种). 最终也是基本类型.
有了这些类型结构后, 如何保存一个变量就很清晰了, 那么生成变量的序列化/反序列化代码也就很清晰了.
代码生成器通过变量类型结构生成序列化/反序列化代码.
说明:
根标签名称:structure_def:
类型标签:
basetype(主要有char, int, double, long, float, std::string这些类型)
class(用户定义的类)
struct(用户定义的结构体)
stltype(主要有std::vector, std::list, std::map, std::set)
typedef(使用typedef定义的类型)
stltemplate(使用typedef定义的stltype, 例如typedef std::vector<int> IntVector)
类型标签的属性:
name(类型名称, 基本类型, stl的一些类型, 用户定义的类/结构体等的名称, 例如int, double, CTest, STTest, IntVector等)
typenamecount(stltype类型中模板参数的个数, 例如std::vector模板参数个数是1, std::map模板参数个数是2)
beptr(表示该类型是否为指针类型, 0为否, 1为是)
beptr1(表示stltemplate类型中第一个模板参数是否为指针类型, 0为否, 1为是)
beptr2(表示stltemplate类型中第二个模板参数是否为指针类型, 0为否, 1为是, 如果有的话)
type(表示stltemplate类型中的stltype类型的类名称)
typename1(表示stltemplate类型中第一个模板参数类型的类名称)
typename2(表示stltemplate类型中第二个模板参数类型的类名称)
变量标签: ClassObject(用于记录需要序列化的变量名称和类型), ClassObject的子项就是使用变量名的标签, 变量名标签的class属性代表变量类型.
一. 定义数据对象的XML标签结构
例如:<ObjectSerialization> <m_nA class = "int"> 5 </m_nA> <m_dB class = "double"> 5.900000 </m_dB> <m_intVector class = "IntVector"> <vectorItem0 class = "int"> 1 </vectorItem0> <vectorItem1 class = "int"> 3 </vectorItem1> <vectorItem2 class = "int"> 4 </vectorItem2> <vectorItem3 class = "int"> 7 </vectorItem3> </m_intVector> </ObjectSerialization>
根标签: ObjectSerialization
第2级标签: 变量名 例如m_nA
标签的内容: 变量值 例如标签m_nA的内容是5, 那么变量m_nA的值就是5
标签属性:
class: 变量的类型(类名), 例如 int, double, IntVector
class的值有: int, double, long, char, std::string, 使用typedef定义的类型, 使用typedef定义的stl容器类型(std::vector, std::map, std::list, std::set)
二. 变量的序列化与反序列化.
使用XML序列化变量过程就是写入XML过程, 反序列化过程就是读取XML过程.
(每一个XML解析器的调用流程可能有区别).
现在有
int m_nA = 0;
int m_nB = 1;
和
struct CTest
{
double m_dC;
double m_dD;
};
CTest m_test;
// 序列化/反序列化的伪代码
Write_int();
Write_double();
Write_m_nA()
{
Write_int(m_nA);
}
Write_m_nB()
{
Write_int(m_nB);
}
Write_CTest()
{
Write_double(m_dC);
Write_double(m_dD);
}
三. 序列化/反序列化的代码需要跟着这些变量结构变化的
现在CTest结构改变为struct CTest
{
double m_dC;
int m_nD;
};
// 伪代码
Write_CTest()
{
Write_double(m_dC);
Write_int(m_nD);
}
变量类型结构的变化, 序列化/反序列化的代码也会跟需要变化, 这种变化在一些复杂的数据机构中, 代码修改起来是很繁琐和重复的, 很容易出错. 但是这种变化又是有规律的. 既然有规律, 就可以用代码写一个程序去固定它和规范它.
在MFC中就是使用宏来把这种变化规律来固定的.
在boost中是使用模板和宏来把这种变化规律来固定的.
我这里则写了一个程序自动生成变量的序列化/反序列化代码来固定.
也就是说变量的类型结构变化了, 程序将根据类型结构的变化自动生成该变量的序列化/反序列化的代码.
(这里说的非常绕口啊)
概括说一句就是: 我写一个小程序, 该小程序能根据变量的类型结构自动生成变量的序列化/反序列化的代码.
(就是用代码来写代码, 或者说在代码之上写代码, 这个程序就是一个代码生成器).
四. 实现原理和过程
4.1 生成变量的序列化/反序列化代码所需要的信息
从点一中的变量存储在XML中的结构知道需要的信息有:A. 变量名.
B. 变量类型的结构
C. XML的操作代码.
有了这3类信息, 即可自动生成变量的序列化/反序列化代码.
其中B.变量类型的结构
4.2 变量类型的结构
从点一中的变量存储在XML中的内容知道, 最终写入XML标签树的树叶部分的是数字和字符. 标签之间的结构则反映类型结构.所以变量类型的结构分类有:
A. 基本类型: char, int, double, long, float, std::string (我这里把std::string作为基本类型, 也就是字符, 因为我std::string使用的非常多).
B. struct和class: 也就是结构体和类, 结构体和类的成员层层下去, 最终也是基本类型.
C. typedef定义的类型: typedef定义A和typedef定义B, 最终也是基本类型.
D. stl定义的容器: 有std::vector, std::list; std::map; std::set(我用得最多也就这几种). 最终也是基本类型.
有了这些类型结构后, 如何保存一个变量就很清晰了, 那么生成变量的序列化/反序列化代码也就很清晰了.
代码生成器通过变量类型结构生成序列化/反序列化代码.
4.3 变量类型的结构的表示和描述
用XML描述如下:<structure_def> <class name = "CTest"> <include file = "a" sys = "0"> </include> <include file = "b" sys = "1"> </include> </class> <basetype name = "int"> </basetype> <basetype name = "double"> </basetype> <basetype name = "long"> </basetype> <stltype name = "std::vector" typenamecount = "1"> </stltype> <stltemplate beptr = "0" beptr1 = "0" name = "IntVector" type = "std::vector" typename1 = "int"> </stltemplate> <ClassObject> <m_nA class = "int"> </m_nA> <m_dB class = "double"> </m_dB> <m_intVector class = "IntVector"> </m_intVector> </ClassObject> </structure_def>
说明:
根标签名称:structure_def:
类型标签:
basetype(主要有char, int, double, long, float, std::string这些类型)
class(用户定义的类)
struct(用户定义的结构体)
stltype(主要有std::vector, std::list, std::map, std::set)
typedef(使用typedef定义的类型)
stltemplate(使用typedef定义的stltype, 例如typedef std::vector<int> IntVector)
类型标签的属性:
name(类型名称, 基本类型, stl的一些类型, 用户定义的类/结构体等的名称, 例如int, double, CTest, STTest, IntVector等)
typenamecount(stltype类型中模板参数的个数, 例如std::vector模板参数个数是1, std::map模板参数个数是2)
beptr(表示该类型是否为指针类型, 0为否, 1为是)
beptr1(表示stltemplate类型中第一个模板参数是否为指针类型, 0为否, 1为是)
beptr2(表示stltemplate类型中第二个模板参数是否为指针类型, 0为否, 1为是, 如果有的话)
type(表示stltemplate类型中的stltype类型的类名称)
typename1(表示stltemplate类型中第一个模板参数类型的类名称)
typename2(表示stltemplate类型中第二个模板参数类型的类名称)
变量标签: ClassObject(用于记录需要序列化的变量名称和类型), ClassObject的子项就是使用变量名的标签, 变量名标签的class属性代表变量类型.
4.4 通过类类型信息生成变量的序列化/反序列化代码
代码生成器提供用户定义各种类的操作和定义各种变量的操作, 有了这些数据, 代码生成器即可生成变量的序列化/反序列化的代码. 用户把代码拷贝到自己的工程作简单的配置修改, 编译即可.相关文章推荐
- 序列化对象到Xml文件以及反序列话Xml文件到对象(序列化数据到8个Java原型类型)
- XML序列化数据对象(三)
- 格式化程序尝试对消息反序列化时引发异常: 尝试对参数 http://tempuri.org/ 进行反序列化时出错: GetLzdtArticleResult。InnerException 消息是“反序列化对象 属于类型 lzdt.DTO.Dtolzdt[] 时出现错误。读取 XML 数据时,超出最大
- XML序列化数据对象(一)
- wcf序列化大对象时报错:读取 XML 数据时,超出最大
- 【C#】解决进行反序列化时出错:。InnerException 消息是“反序列化对象 属于类型 System.String 时出现错误。读取 XML 数据时,超出最大字符串内容长度配额 (8192)。
- InnerException 消息是“反序列化对象 属于类型 *** 时出现错误。读取 XML 数据时,超出最大字符串内容长度配额 (8192)。(注意细节)
- InnerException 消息是“反序列化对象 属于类型 *** 时出现错误。读取 XML 数据时,超出最大字符串内容长度配额 (8192)。(注意细节)
- java 使用xom对象数据序列化为xml、反序列化、Preferences相关操作小案例
- XmlSerializer 对象的Xml序列化和反序列化
- 使用XStream将对象序列化到XML以及从XML反序列化到对象
- javascript中XMLHttpRequest对象同步获取XML数据
- 只需要一步即可将xml数据转化成自定义类的对象模型
- xml和对象直接的序列化和反序列化
- 【黑马Android】(02)短信发送器/布局演示/android下单位/android下Junit/保存数据/android下权限/xml解析和序列化
- Java对象序列化和XML
- 用 XStream 序列化/反序列化 XML 为 Java 对象(实例)
- XML到Java代码的数据绑定之对象
- Ajax处理XML,XMLHttpRequest对象的创建和访问servlet并返回xml数据到页面展示
- C#中xml文件和对象的序列化与反序列化