2

The code below generates a xml file but , when it loops theough a map , it always names the map key as first and value as second

Is there a way that we can customise tag names first and second to groupid and groupType as shown in desired output

 #include <fstream>
#include <boost/serialization/map.hpp>
#include <boost/serialization/nvp.hpp>
#include <boost/archive/xml_oarchive.hpp>
#include <string>
#include <iostream>
#include <map>

using namespace std;

class MyConnections
{
  public:
    MyConnections()
    {

       e_group.insert( std::make_pair(1,"ETOTO") ) ;
       e_group.insert( std::make_pair(2,"ETOTO") ) ;

   }

    template<class archive>
    void serialize(archive& ar, const unsigned int version)
    {
        using boost::serialization::make_nvp;
        ar & make_nvp("Connections", e_group);
    }

  public:
   typedef   map<int,std::string> groups;
   groups  e_group;
};

int main(int argc, char* argv[])
{
    std::ofstream ofs("output.xml");
    const MyConnections conn;
    boost::archive::xml_oarchive xml(ofs);
    xml << boost::serialization::make_nvp("Connections", conn);
}

Current Output:

     <?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE boost_serialization>
<boost_serialization signature="serialization::archive" version="14">
<Connections class_id="0" tracking_level="0" version="0">
        <Connections class_id="1" tracking_level="0" version="0">
                <count>2</count>
                <item_version>0</item_version>
                <item class_id="2" tracking_level="0" version="0">
                        <first>1</first>
                        <second>ETOTO</second>
                </item>
                <item>
                        <first>2</first>
                        <second>ETOTO</second>
                </item>
        </Connections>
</Connections>
</boost_serialization>

Desired Output

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE boost_serialization>
<boost_serialization signature="serialization::archive" version="14">
<Connections class_id="0" tracking_level="0" version="0">
        <Connections class_id="1" tracking_level="0" version="0">
                <count>2</count>
                <item_version>0</item_version>
                <item class_id="2" tracking_level="0" version="0">
                        <groupid>1</groupid>
                        <groupType>ETOTO</groupType >
                </item>
                <item>
                        < groupid >2</groupid >
                        < groupType >ETOTO</groupType >
                </item>
        </Connections>
</Connections>
</boost_serialization>
LearningCpp
  • 972
  • 12
  • 29

1 Answers1

2

Serialization for the map is a generic implementation.

You can of course provide a /better match/ and override the naming:

namespace boost { namespace serialization { 
    template <typename Ar>
        void serialize(Ar& ar, std::pair<int const, std::string>& p, unsigned) {
            ar & make_nvp("groupid", p.first) & make_nvp("groupType", p.second);
        }
} }

See it Live On Coliru

This prints (excerpt):

<Connections class_id="1" tracking_level="0" version="0">
    <count>2</count>
    <item_version>0</item_version>
    <item class_id="2" tracking_level="0" version="0">
        <groupid>1</groupid>
        <groupType>ETOTO</groupType>
    </item>
    <item>
        <groupid>2</groupid>
        <groupType>ETOTO</groupType>
    </item>
</Connections>

Of course, this has the problem that ALL maps of int -> string get the same naming, so be sure to look at http://www.boost.org/doc/libs/1_63_0/libs/serialization/doc/strong_typedef.html

Disclaimer

I'd suggest that if you want/need this level of control, you shouldn't not be using XML archive.

sehe
  • 374,641
  • 47
  • 450
  • 633
  • Would u tell me what would be the good approach and why shouldn't I use xml archive – LearningCpp Mar 28 '17 at 03:54
  • And sorry I did not understand the strong typedef , is that better than above code ? Iam new to boost a db would u help me using it – LearningCpp Mar 28 '17 at 04:06
  • Nevermind about the strong typedef as long as you keep the caveat in mind: _"Of course, this has the problem that ALL maps of `int -> string` get the same naming"_. – sehe Mar 28 '17 at 06:44
  • 1
    This also hints at why Boost Serialization isn't the right choice if you want to layout the XML any particular way. Boost Serialization does compositional, _generic_ archive creation. The direct consequence of this is that you cannot care about the layout. (That's the opposite of generic). The reason for any names at all is technical ("XML requires it"). I personally feel they might better have been automatically named, leaving just ordering of elements like in all other formats. – sehe Mar 28 '17 at 06:48
  • Will it be the same if I use prop tree , would you please help me with prop tree approach for the same – LearningCpp Mar 28 '17 at 06:50
  • Or does proptree follow same convention – LearningCpp Mar 28 '17 at 06:50
  • PropertyTree allows you to plan the tree layout (this is then your responsibility, so it is strictly more work). However it's not an XML library. Consider something like libxml2 or PugiXML. I have many answers using both Boost Property Tree and PugiXML. Feel free to browse for examples – sehe Mar 28 '17 at 06:59
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/139216/discussion-between-learningcpp-and-sehe). – LearningCpp Mar 28 '17 at 07:33
  • Also should i override the naming in boost source code or my header file where this structure is defined , if i do it in my header, how will it effect other map structure – LearningCpp Mar 28 '17 at 07:38
  • And the xml iam trying to create is not simple as posted in this post , it basically is a `map of set of maps to a structure` , can u help me how to use property tree for creating a xml file by looping through the simple map initilayy, i tried searhing it but no where i found map travesal and xml creation – LearningCpp Mar 28 '17 at 07:48
  • if i have a map , it works here , but not in my code – LearningCpp Mar 28 '17 at 08:08
  • 1
    @sehe, "automatically named", even better: optionally automatically named. So one isn't force to use BOOST_SERIALIZATION_NVP is all custom serialize functions. Although it is always very tempting to start from Boost.Serialization and wanting to have more and more readable output (and even modifiable manually to certain extent). I think it is easier to start from serialization and hack the flexibility than the other way around (start from ad hoc output/input and hack serious serialization) – alfC Aug 21 '19 at 08:38