增强基于 XML class_id的反序列化
Boost XML class_id based deserialization
我有一个XML序列化的反射类型,我可以像这样获得它的序列化:
template <typename Archive>
std::function<void(Archive&,unsigned)> get_serialization_for_type(std::string name);
这些类型都具有带有提升序列化库的 GUID 集,因此它们在 XML 中的class_id
属性与有效名称匹配。如何反序列化这些类型?有没有办法获取存档正在读取的当前节点的属性?也欢迎对不同方法提出建议,但我无法更改 XML 的格式。
示例 XML:
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE boost_serialization>
<boost_serialization signature="serialization::archive" version="17">
...
<container class_id="23" tracking_level="0" version="0">
<count>2</count>
<typeA class_id="type_a" tracking_level="0" version="0">
...
</typeA>
<typeB class_id="type_b" tracking_level="0" version="0">
...
</typeB>
</container>
...
</boost_serialization>
这看起来像一个常规的 Boost 序列化 XML 存档。你为什么不以与你写它完全相同的方式阅读它?
我的意思基本上是这样的:这段代码序列化和反序列化具有不同类型和属性的多态元素的容器。
它使用"相同"代码进行序列化和反序列化。
原则上,如果 XML 确实是由 Boost 序列化生成的,则应该能够利用此模式。
住在科里鲁
#include <boost/archive/xml_oarchive.hpp>
#include <boost/archive/xml_iarchive.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/serialization/unique_ptr.hpp>
#include <boost/serialization/assume_abstract.hpp>
#include <boost/serialization/export.hpp>
#include <iostream>
#include <sstream>
#include <boost/core/demangle.hpp>
namespace MyLib {
struct Base {
using BaseContainer = std::vector<std::unique_ptr<Base> >;
virtual ~Base() = default;
int a, b, c;
};
struct A : Base {
std::string d, e, f;
};
struct B : Base {
float h, i, j;
};
template <typename Ar> void serialize(Ar& ar, Base& base, unsigned) {
ar & BOOST_SERIALIZATION_NVP(base.a)
& BOOST_SERIALIZATION_NVP(base.b)
& BOOST_SERIALIZATION_NVP(base.c)
;
}
template <typename Ar> void serialize(Ar& ar, A& a, unsigned) {
ar & boost::serialization::make_nvp("Base", boost::serialization::base_object<Base>(a))
& BOOST_SERIALIZATION_NVP(a.d)
& BOOST_SERIALIZATION_NVP(a.e)
& BOOST_SERIALIZATION_NVP(a.f)
;
}
template <typename Ar> void serialize(Ar& ar, B& b, unsigned) {
ar & boost::serialization::make_nvp("Base", boost::serialization::base_object<Base>(b))
& BOOST_SERIALIZATION_NVP(b.h)
& BOOST_SERIALIZATION_NVP(b.i)
& BOOST_SERIALIZATION_NVP(b.j)
;
}
using BaseContainer = std::vector<std::unique_ptr<Base> >;
}
//BOOST_SERIALIZATION_ASSUME_ABSTRACT(MyLib::Base)
BOOST_CLASS_EXPORT(MyLib::Base)
BOOST_CLASS_EXPORT_GUID(MyLib::A, "type_A")
BOOST_CLASS_EXPORT_GUID(MyLib::B, "type_B")
int main() {
std::stringstream xml;
{
MyLib::BaseContainer container;
container.emplace_back(std::make_unique<MyLib::A>());
container.emplace_back(std::make_unique<MyLib::B>());
container.emplace_back(std::make_unique<MyLib::B>());
container.emplace_back(std::make_unique<MyLib::A>());
boost::archive::xml_oarchive oa(xml);
oa << BOOST_SERIALIZATION_NVP(container);
}
//std::cout << xml.str();
{
boost::archive::xml_iarchive ia(xml);
MyLib::BaseContainer container;
ia >> BOOST_SERIALIZATION_NVP(container);
for (auto& el : container) {
std::cout << "Element of type " << boost::core::demangle(typeid(*el).name()) << "n";
}
}
}
指纹:
Element of type MyLib::A
Element of type MyLib::B
Element of type MyLib::B
Element of type MyLib::A
相关文章:
- 如何知道QDataStream不能反序列化某些内容
- 增强基于 XML class_id的反序列化
- 提升反序列化对象具有 nan 或 -nan 值
- 如何在 c++ 非托管代码中反序列化 byte[] 的 json 字符串?
- 如何反序列化数组?
- Protobuf中重复字段的问题.使用重复字段进行序列化/反序列化的更好方法是什么?
- 通过 tcp 发送 C# 类并在 C++ 上反序列化
- 序列化和反序列化boost共享指针
- 在C++中使用POCO和grain对多个对象进行反序列化
- C++中整数向量的序列化/反序列化
- 使用 Json 转换器反序列化 WCF 服务中的C++字符串
- 使用 QDataStream 对原始数据进行反序列化
- 使用协议缓冲区创建通用反序列化程序
- 如何在C++中从头开始反序列化文件(没有库)
- 在协议缓冲区 c++ 中反序列化字符串数组
- 在进程的内存中序列化/反序列化
- 谷物/C++ 11 - 如何指定反序列化的可选参数
- 是否可以反序列化(从原始内存块)没有默认构造函数的对象?
- 如何从平面缓冲区中反序列化联合结构的 void* 值的大小
- 用 Boost 反序列化犰狳 colvec