最近在做C++项目,需要序列化和反序列化json以及xml数据。可能是由于用惯了C#等更高度化语言,搜了一遍,发现C++没有特别方便使用的序列化、反序列化的库。大部分库都是为了实现功能(非常感谢这些实现库的作者),使用时,需要根据字段深度定义结构体字段(这一步无法省略),然后再使用手动编写方式进行json/xml对字段进行赋值。因此,在使用便捷上,比C#、JAVA等还是略差一筹。其中,有一个库(忘了名字)实现了通过在结构体最后面定义一个宏罗列所有字段的方式,省略了手动编写赋值的麻烦,易用性提升了一步,但仍然存在一个问题,就是结构体字段比较多时,经常忘记定义字段和宏枚举之间要一并处理,因此,使用上,比C#、JAVA还是略差一筹。
基于以上问题,本人对已有开源的json、xml功能实现库进行二次封装,赋予功能实现库更便捷的使用。其中,json使用jsoncpp开源库,xml使用 tinyxml2开源库,开源库地址:
json:https://github.com/open-source-parsers/jsoncpp
xml:https://github.com/leethomason/tinyxml2
本人二次封装的源码地址:
EasySerialize:https://files.cnblogs.com/files/blogs/476708/EasySerialize.zip?t=1692439662&download=true
基于这两个开源库,再进行简单封装,达到只需要按格式定义结构体,不需要编写赋值的实现效果。详细使用,请查源码中的测试列子。
1、XML
xml分为两种节点: Element 和 Attribute 。分别对应xml的内容节点和属性。定义xml的结构体时,需根据实际的xml文件格式定义。
xml节点分为 简单节点、复杂单节点、链表节点 三种。
1)简单节点:此节点 没有属性,其内容也没有保护其他复杂节点(即内容是简单的字符串),使用XmlString、XmlInt32、XmlBool等基本xml类型表示。下面 str1 和 int2 节点都属于简单节点。
<testxml>
<str1>test1</str1>
<int2>200</int2>
</testxml>
EasySerialize的xml结构体表示:
struct XmlInfo : XmlBase
{
XmlString str1 XmlElement("str1");
XmlInt32 int2 XmlElement("int2");
};
说明:XmlString表示str1节点的内容是string类型,为简单节点类型,但其本身是一个 Element 类型的节点,而非属性。同理,int2也是简单节点,但其内容为int32类型,其本身也是一个xml节点。
2)复杂的单节点:节点内容是复杂的,嵌套了其他的节点,或者带了属性,但没有同名的兄弟节点,使用XmlObject<T>表示。下面 obj1属于复杂单节点。
<testxml>
<obj1>
<element1>objele1</element1>
<element2>255</element2>
<element3 attr1="testattr1" attr2="500">content_with_attr</element3>
</obj1>
</testxml>
EasySerialize的xml结构体表示:
struct SimpleNode2 : XmlBase
{
XmlString ContentWithAttribute XmlSimpleContent("simplenode2");
XmlString Attribute1 XmlAttribute("attr1");
XmlInt32 Attribute2 XmlAttribute("attr2");
};
struct ObjectNode : XmlBase
{
XmlString Element1 XmlElement("element1");
XmlInt32 Element2 XmlElement("element2");
XmlObject<SimpleNode2> Element3 XmlElement("element3");
};
struct XmlInfo : XmlBase
{
XmlObject<ObjectNode> obj1 XmlElement("obj1");
};
说明:obj1是一个复杂的单节点,里面又包含了3个element,而其中Element3又是一个复杂节点,因为它带了属性。例子中,除了element外,还有attr1和attr2为属性节点,而ContentWithAttribute,它只是为了存储element3的内容(即例子中的content_with_attr),此内容为string类型,并且既不是element节点,也不是attribute节点,因此,定义为XmlSimpleContent。
3)链表节点:存在同名的兄弟节点,则为链表节点,使用XmlArray<T>表示。下面item节点为链表节点,每个item为链表的一个元素。
<testxml>
<obj2>
<item>item1content</item>
<item>item2content</item>
<item>item3content</item>
</obj2>
</testxml>
EasySerialize的xml结构体表示:
struct SimpleNode1 : XmlBase
{
XmlString OnlyContent XmlSimpleContent("simplenode1");
};
struct ObjectArr : XmlBase
{
XmlArray<SimpleNode1> Arrays XmlElement("item");
};
struct XmlInfo : XmlBase
{
XmlObject<ObjectArr> obj2 XmlElement("obj2");
};
说明:obj2本身是一个复杂的单节点(因为它没有同名的兄弟节点,因此不是链表,但其内容是复杂内容),其内容为一个链表节点,而每个元素节点都是简单节点。
2、json
json相对简单,直接查看源码例子即可。
标签:xml,EasySerialize,struct,C++,链表,XmlElement,序列化,节点 From: https://www.cnblogs.com/lishide/p/17642833.html