Это похоже на обычный Boost Serialization XML архив. Почему бы вам не прочитать его точно так же, как вы его написали?
Что я имею в виду в основном так: этот код сериализует и десериализует контейнер полиморфных c элементов с различными типами и properties.
Это делается с использованием «одного и того же» кода для сериализации и десериализации.
В принципе вы должны иметь возможность использовать этот шаблон, если XML действительно генерируется Повышенная сериализация.
Live On Coliru
#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