XML序列化数据对象(三)
2013-07-27 10:43
561 查看
XML序列化数据对象(三) --- 实现
图1
图2
图3
图4
图5
假设CTest类的结构变化了, 那么序列化/反序列化的代码也就需要改变了, 你可以重新加载aa.xml对CTest的结构修改, 然后再次生成序列化/反序列化代码即可.
aa.xml文件:
以上这些代码都是自动生成的, 随类型结构的变化而变化.
以后要序列化某类型的变量, 可以简单的生成这些代码即可.
把h文件和cpp文件加入到你的工程即可.
序列化:
生成的变量的序列化信息ss.xml文件是
反序列化:
初步使用了一下, 效果还可以.
3.2 添加类类型的处理非常非常的繁琐和乱, 因为类型很多(basetype, stltype, struct, class, stltemplate, typedef), 还有很多判断条件, 这些判断我是通过界面交互来处理的, 可能还有很多没有考虑到的地方. 可惜自己不懂C++的语法分析, 通过语法分析, 就很容易分析出这些类型, 而且更强大.
3.3 设计成类似boost库那样序列化的操作方式是不是更好?
3.4 用代码写代码需要在更高一层上想问题. 平时写代码, 你直接把代码写入对应的cpp/h文件, 然后编译, 看是否有语法错误, 编译通过了, 就运行看有没有运行上/逻辑上的错误;用代码写代码还要加多一层, 就是你先确保生成代码的程序(代码生成器)编译运行没错, 然后编译生成器生成的代码, 假设这代码有语法错误, 你需要返回到生成器工程对应的字符地方修改这些字符, 如果生成的代码语法没有但运行有错, 那还要分析你所设计的生成代码是否有问题. 这种过程是不断的在生成器代码和被生成代码之间切换, 编译, 生成, 拷贝, 编译..... (有时候会很乱!)
3.5 通过序列化/反序列化代码生成器, 体会到用代码写代码跟C++的模板编程(泛化编程)有与曲同工之妙! 必须在更高一层处想问题.当然泛化编程更规范, 更标准. (看这文章).
3.6 C++代码生成器生成代码, 生成的代码要编译后才能用, 这是因为C++的语言特性决定的. 假设我有一个代码生成器, 生成的代码不需要编译, 能直接使用, 那多好啊. 脚本语言可以(看这文章).
一. 实现界面
1.1 大致界面
图1
1.2 类类型
图2
1.3 变量输入
图3
二. 使用步骤
2.1 添加一些类
图4
2.2 添加一些变量
图5
2.3 可以保存类型和变量为xml文件
添加了类型和变量后, 这些数据可以保存为xml文件(例如aa.xml), 也可以重新加载这个XML文件, 方便以后修改使用.假设CTest类的结构变化了, 那么序列化/反序列化的代码也就需要改变了, 你可以重新加载aa.xml对CTest的结构修改, 然后再次生成序列化/反序列化代码即可.
aa.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>
2.4 生成序列化/反序列化的代码
#pragma once // 这里include你自己的头文件 // 序列化 class CHYSerialization { public: CHYSerialization(); ~CHYSerialization(); bool SerializationOpen(const std::string& strFileName); bool SerializationClose(); // 基本类型的序列化 bool SerializationClassType_int(CHYMLItem* pCHYMLItemParent, const std::string& strObjectName, const int& nValue); bool SerializationClassType_long(CHYMLItem* pCHYMLItemParent, const std::string& strObjectName, const long& lValue); bool SerializationClassType_double(CHYMLItem* pCHYMLItemParent, const std::string& strObjectName, const double& dValue); bool SerializationClassType_float(CHYMLItem* pCHYMLItemParent, const std::string& strObjectName, const float& fValue); bool SerializationClassType_char(CHYMLItem* pCHYMLItemParent, const std::string& strObjectName, const char& chValue); bool SerializationClassType_string(CHYMLItem* pCHYMLItemParent, const std::string& strObjectName, const std::string& strValue); // 用户定义的类/结构体等类型的序列化 bool SerializationClassType_CTest(CHYMLItem* pCHYMLItemParent, const std::string& strObjectName, const CTest& refValue); bool SerializationClassType_IntVector(CHYMLItem* pCHYMLItemParent, const std::string& strObjectName, const IntVector& refValue); // 变量的序列化函数 bool SerializationObject_m_nA(const int& refValue); bool SerializationObject_m_dB(const double& refValue); bool SerializationObject_m_intVector(const IntVector& refValue); private: CHYML m_hyML; // 你使用的XML解析库相关变量 CHYMLParser m_hyMLParser; CHYMLItem* m_pCHYMLItemParent; std::string m_strFileName; }; // 反序列化 class CHYReSerialization ... // Cpp文件代码很长 ...
以上这些代码都是自动生成的, 随类型结构的变化而变化.
以后要序列化某类型的变量, 可以简单的生成这些代码即可.
把h文件和cpp文件加入到你的工程即可.
2.5 序列化/反序列化的代码的使用
变量m_nA, m_dB, m_intVector本身就是你的工程里面需要才添加到代码生成器的.序列化:
// 你工程里的变量是这样的 int m_nA = 5; double m_dB = 5.9; IntVector m_intVector; m_intVector.push_back(1); m_intVector.push_back(3); m_intVector.push_back(4); m_intVector.push_back(7); .... // 序列化 CHYSerialization hySerialization; hySerialization.SerializationOpen("C:\ss.xml"); // 变量的序列化信息保存在ss.xml文件中 // 序列化这3个变量 hySerialization.SerializationObject_m_nA(m_nA); hySerialization.SerializationObject_m_dB(m_dB); hySerialization.SerializationObject_m_intVector(m_intVector); hySerialization.SerializationClose();
生成的变量的序列化信息ss.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>
反序列化:
CHYReSerialization hyReSerialization; hyReSerialization.ReSerializationOpen("C:\ss.xml"); hyReSerialization.ReSerializationObject_m_nA(m_nA); hyReSerialization.ReSerializationObject_m_dB(m_dB); hyReSerialization.ReSerializationObject_m_intVector(m_intVector); hyReSerialization.ReSerializationClose();
初步使用了一下, 效果还可以.
三. 总结
3.1 这样自动生成序列化/反序列化的代码使用起来的确比较方便, 但是也有繁琐的地方, 例如生成代码后, 还要把h文件和cpp文件拷贝到自己的工程, 还要在h文件中添加相关的头文件(你的类头文件). 对比boost库, 只需要些相关的模板代码代码就可以了.反正就是没有boost库方便.3.2 添加类类型的处理非常非常的繁琐和乱, 因为类型很多(basetype, stltype, struct, class, stltemplate, typedef), 还有很多判断条件, 这些判断我是通过界面交互来处理的, 可能还有很多没有考虑到的地方. 可惜自己不懂C++的语法分析, 通过语法分析, 就很容易分析出这些类型, 而且更强大.
3.3 设计成类似boost库那样序列化的操作方式是不是更好?
3.4 用代码写代码需要在更高一层上想问题. 平时写代码, 你直接把代码写入对应的cpp/h文件, 然后编译, 看是否有语法错误, 编译通过了, 就运行看有没有运行上/逻辑上的错误;用代码写代码还要加多一层, 就是你先确保生成代码的程序(代码生成器)编译运行没错, 然后编译生成器生成的代码, 假设这代码有语法错误, 你需要返回到生成器工程对应的字符地方修改这些字符, 如果生成的代码语法没有但运行有错, 那还要分析你所设计的生成代码是否有问题. 这种过程是不断的在生成器代码和被生成代码之间切换, 编译, 生成, 拷贝, 编译..... (有时候会很乱!)
3.5 通过序列化/反序列化代码生成器, 体会到用代码写代码跟C++的模板编程(泛化编程)有与曲同工之妙! 必须在更高一层处想问题.当然泛化编程更规范, 更标准. (看这文章).
3.6 C++代码生成器生成代码, 生成的代码要编译后才能用, 这是因为C++的语言特性决定的. 假设我有一个代码生成器, 生成的代码不需要编译, 能直接使用, 那多好啊. 脚本语言可以(看这文章).
相关文章推荐
- 格式化程序尝试对消息反序列化时引发异常: 尝试对参数 http://tempuri.org/ 进行反序列化时出错: GetLzdtArticleResult。InnerException 消息是“反序列化对象 属于类型 lzdt.DTO.Dtolzdt[] 时出现错误。读取 XML 数据时,超出最大
- XML序列化数据对象(一)
- wcf序列化大对象时报错:读取 XML 数据时,超出最大
- XML序列化数据对象(二)
- InnerException 消息是“反序列化对象 属于类型 *** 时出现错误。读取 XML 数据时,超出最大字符串内容长度配额 (8192)。(注意细节)
- InnerException 消息是“反序列化对象 属于类型 *** 时出现错误。读取 XML 数据时,超出最大字符串内容长度配额 (8192)。(注意细节)
- 【C#】解决进行反序列化时出错:。InnerException 消息是“反序列化对象 属于类型 System.String 时出现错误。读取 XML 数据时,超出最大字符串内容长度配额 (8192)。
- 序列化对象到Xml文件以及反序列话Xml文件到对象(序列化数据到8个Java原型类型)
- java 使用xom对象数据序列化为xml、反序列化、Preferences相关操作小案例
- 如何让ActiveXObject( "Microsoft.XmlDom ")对象在非IE浏览器下显示数据?firefox(火狐)
- javascript中XMLHttpRequest对象同步获取XML数据
- 只需要一步即可将xml数据转化成自定义类的对象模型
- DateTime数据类型的XML序列化及时区问题(存档)
- C#温故而知新学习系列之XML编程—5-XmlSerializer类把对象序列化为XML文档
- .NET对象的XML序列化和反序列化
- java 对象序列化xml方法
- 【黑马Android】(02)短信发送器/布局演示/android下单位/android下Junit/保存数据/android下权限/xml解析和序列化
- .NET 和Java 对象 XML序列化 库WOX
- AJAX-----07XMLHttpRequest对象的处理返回的JSON类型数据
- 对象的Xml序列化和反序列化