王玉龙 宁蒙 王卫涛
(中国船舶集团公司第七一三研究所 河南省郑州市 450015)
在某型号物资管理调度系统中,既有基于国产平台的中标麒麟操作系统[1],也有基于安卓平台的嵌入式系统,在每个计算机节点中需将启动信息、运行信息等进行本地化,并且部分节点之间通过网络以XML形式传输给任务接收终端,任务接收后需要将数据本地化及存储至人大金仓数据库[2]。另外任务执行情况和物资盘点信息也要通过网络以XML形式发送到管理调度计算机节点,最后这些信息存储在人大金仓数据库服务器中。不仅仅系统本身存在数据交换,与外系统之间也存在数据交换的需求,物资管理调度系统需要提供网络接收外部系统的基础数据信息,比如人员、单位、任务等数据信息。此外物资管理调度系统还需将一些数据信息发布出去,供其他系统使用,这些信息在各系统之间进行交换时,都是以XML协议作为数据交换的载体。
该物资管理调度系统所在的数字化平台数据来源复杂,信息量巨大,包括外围设备的实时采集数据、设备信息、调度过程数据、盘库信息等,需要对其中的关键数据信息进行持久保存和在进程间进行传输。借鉴前期项目采用基于.net的自带序列化反序列库[3]可以解决此类问题。XML序列化就是将对象状态转换为XML文件,反序列化则是将XML文件转换为对象实例,这两个过程可以轻松实现存储和传输数据[4]。
本文提出一种基于Qt跨平台的XML序列化反序列化框架来解决国产操作系统平台间的数据交换和共享问题,该框架扩展性强,成员变量可以为基础数据类型(Int、QString、QBool、QDateTime等)、集合类型(QList、QMap等)以及自定义类型(指针)实现XML序列化反序列化功能,有效解决了信息存储、传输和共享的问题。
利用面向对象程序设计中的继承以及虚函数概念[5],结合Qt中元对象机制,自研对业务软件提供的XML序列化和反序列化功能。下面对XML序列化和反序列化算法设计分别进行详细说明。
XML序列化就是通过对外接口将类对象转化为可以网络传输或者本地保存的XML文件,核心思想是将类的名称映射成XML文件的根节点元素;不同类型的各成员变量名称映射为XML文件的属性名称;成员变量的值映射为xml文件内的属性值;对于成员变量为基础数据类型的变量较容易映射,但是集合类型(QList、QMap等)以及自定义类型(指针)需要进行复杂的嵌套循环和基类指针调用;下面对XML序列化功能设计相关的自研函数进行详细说明,见表1所示。
图1:序列化功能内部函数之间调用图
其中函数InstanceToXml()为序列化功能的唯一对外接口,实现将类实例转换为XML文件,函数与函数之间的调用关系见图1所示。
XML序列化功能内部主要函数接口instanceToXml的实现流程主要分以下步骤,详细流程如图2所示。
(1)首先获取待序列化实例的元对象(MetaObj);
(2)通过元对象(MetaObj)得到序列化类的N个公有成员变量;
(3)依次遍历N个公有成员变量,并且判断当前成员变量是什么类型;
(4)若为list集合类型,调用listToXml函数进行增加相应节点;
(5)若为map集合类型,调用mapToXml函数进行增加相应节点;
(6)若为int、string、bool等基础类型,直接增加相应xml节点即可;
(7)若为自定义类型,使用该函数迭代即可;
(8)遍历完所有成员变量,函数退出。
表1:序列化相关函数及说明
表2:反序列化相关函数及说明
表3:某调度台位配置信息(ConsoleConfig)结构
XML反序列化是XML序列化的反过程,通过对外接口将网络传输中XML文件流或者本地保存的XML文件转化类对象,核心思想是将XML文件的根节点元素映射成类的名称;XML文件的属性名称映射为不同类型的各成员变量名称;XML文件内的属性值映射为成员变量的值;对于XML文件或流存在嵌套或者重复结构映射比较复杂,即映射为类中集合类型(QList、QMap等)以及自定义类型(指针)的成员变量;接下来对XML反序列化功能设计相关的自研函数进行详细说明,见表2所示。
图2:序列化---虚函数instanceToXml()流程图
图3:反序列化功能内部函数之间调用图
图4:反序列化---虚函数xmlToInstanse()流程图
图5:XML序列化上层调用代码
其中函数XmlToInstance()为反序列化功能的唯一对外接口,实现将XML文件转换为类实例,函数与函数之间的调用关系见图3所示。XML反序列化功能内部主要函数接口xmlToInstance()的实现流程主要分以下步骤,详细流程如图4所示:
(1)首先获取待反序列化的XML文件的根节点或者自定义类型根节点;
图6:生成“ConsoleConfig.xml”文件
图7:XML反序列化上层调用代码
图8:反序列化程序运行结果
(2)获取实例元对象,并通过元对象得到N个公有成员变量;
(3)依次遍历N个公有成员变量,通过当前成员变量名,使用compareTagName()函数返回相对应结点,接下来判断成员变量的类型,并且一一赋值;
(4)若为list集合类型,调用xmlToList函数对相同成员变量赋值;
(5)若为map集合类型,调用xmlToMap函数对相同成员变量赋值;
(6)若为int、string、bool等基础类型,对当前成员变量赋值;
(7)若为自定义类型,使用该函数迭代并对当前指针变量字段进行赋值;
(8)遍历完所有成员变量,函数退出。
在中标麒麟操作系统桌面版V6.0上,以某调度台位配置信息为例进行仿真说明,该调度台配置信息类(ConsoleConfig)包含了字符串、布尔、时间、集合及自定义类型等类型,具体类结构如表3所示。
首先定义ConsoleConfig类并且对其进行初始化,然后使用序列化功能接口,具体代码如图5所示,运行程序后生成“ConsoleConfig. xml”文件,如图6所示。
接下来将序列化程序生成的“ConsoleConfig. xml”文件进行反序列化,具体代码如图7所示,程序运行结果如图8所示。
根据运行结果看出使用该序列化反序列化方法可以完成相应功能,满足预期效果。
本文利用面向对象程序设计中的继承以及虚函数概念,结合Qt中元对象机制,在国产中标麒麟操作系统上设计开发出一套XML序列化反序列化框架,该框架可扩展性和维护性强并且支持的数据类型(基础类型、集合类型以及自定义类型等)较丰富,可满足大部分物资调度管理系统业务软件的使用需求,提高了软件开发效率和软件产品质量。