Click here to Skip to main content
13,900,697 members
Click here to Skip to main content
Add your own
alternative version

Stats

1.1K views
Posted 14 Mar 2019
Licenced CPOL

Serialize Data to XML

, 14 Mar 2019
Rate this:
Please Sign up or sign in to vote.
How to serialize data to XML

Protocol Buffers are not always an option and you just have to serialize your data to XML. Then what? Luckily, there is a serialization library available from Boost and it makes that pretty easy for us. You don’t even have to modify your existing data structures to write them out as XML: the library is non-invasive.

Let’s say I want to serialize a list of people to a file, and read it back later. My data structures would be defined like this:

struct person
{
	string name;
	int dob;
	string email;
};

using people = vector<person>;

And once a vector of person‘s is serialized, I want it to look something like this:

<people class_id="0" tracking_level="0" version="1">
	<count>2</count>
	<item_version>1</item_version>
	<item class_id="1" tracking_level="0" version="1">
		<person.name>Martin Vorbrodt</person.name>
		<person.dob>19800830</person.dob>
		<person.email>martin@vorbrodt.blog</person.email>
	</item>
	<item>
		<person.name>Dorota Vorbrodt</person.name>
		<person.dob>19810127</person.dob>
		<person.email>dorota@vorbrodt.blog</person.email>
	</item>
</people>

Easy! First, you must define a generic serialize function for your data structure, then you instantiate an XML output archive with an ofstream object and pass it the data. Reading is done by instantiating an XML input archive with an ifstream object and loading the data into a variable. Like this:

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <boost/archive/xml_oarchive.hpp>
#include <boost/archive/xml_iarchive.hpp>
#include <boost/serialization/vector.hpp>
using namespace std;
using namespace boost::archive;
using namespace boost::serialization;

struct person
{
	string name;
	int dob;
	string email;
};

using people = vector<person>;

BOOST_CLASS_VERSION(person, 1);
BOOST_CLASS_VERSION(people, 1);

template<typename Archive>
void serialize(Archive& ar, person& person, const unsigned int version)
{
	ar & BOOST_SERIALIZATION_NVP(person.name);
	ar & BOOST_SERIALIZATION_NVP(person.dob);
	ar & BOOST_SERIALIZATION_NVP(person.email);
}

int main(int argc, char** argv)
{
	person me{"Martin Vorbrodt", 19800830, "martin@vorbrodt.blog"};
	person her{"Dorota Vorbrodt", 19810127, "dorota@vorbrodt.blog"};
	people us{me, her};
	{
		ofstream ofs("data.xml");
		xml_oarchive oa(ofs, boost::archive::no_header);
		oa << make_nvp("people", us);
	}

	people us_too{};
	{
		ifstream ifs("data.xml");
		xml_iarchive ia(ifs, boost::archive::no_header);
		ia >> make_nvp("people", us_too);
	}

	for(auto& p : us_too)
	{
		cout << "Name  : " << p.name << endl;
		cout << "DOB   : " << p.dob << endl;
		cout << "EMail : " << p.email << endl << endl;
	}

	return 1;
}

Program output:

Name  : Martin Vorbrodt
DOB   : 19800830
EMail : martin@vorbrodt.blog

Name  : Dorota Vorbrodt
DOB   : 19810127
EMail : dorota@vorbrodt.blog

The library has built in support for STL containers. It can also write the data in many output formats, not just XML. Luckily, you only have to define one serialization function per data type and it will work with all input and output archives. Heck, you could even define a serialization function for your protocol buffers data types. 😉

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Martin Vorbrodt
Software Developer (Senior)
United States United States
No Biography provided

You may also be interested in...

Comments and Discussions

 
-- There are no messages in this forum --
Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web02 | 2.8.190306.1 | Last Updated 15 Mar 2019
Article Copyright 2019 by Martin Vorbrodt
Everything else Copyright © CodeProject, 1999-2019
Layout: fixed | fluid