Optional XML serialization

Hi, I use xml_woarchive and xml_wiarchive for reading/writing configuration files. It seems work work well for me, but now I'd like to see if I can do more with it... is it possible to load an XML serialized file, but completely IGNORE a subtree of the XML file if desired? eg template <class Archive> void load( Archive & ar, MyConfig & c, const unsigned int version ) { ar >> make_nvp("standard",c.standard); if (some_global_flag_or_whatever) ar >> make_nvp("advanced", c.advanced); else ar.skip("advanced"); // key bit } The motivation is that I want to "register modules" (in my app) that can read/write their configuration in an XML configuration file. But if the module is not registered, I want to skip that part of the configuration file and move on. I figure since the XML format is like a tree, it might/should be possible to ignore an entire segment of the tree. Is it possible? In a related note, the "class_id" bits in xml archives seems to make it difficult for users to hand-edit the XML file... Are these tags required? thanks, Paul

Paul wrote:
Hi,
I use xml_woarchive and xml_wiarchive for reading/writing configuration files.
It seems work work well for me, but now I'd like to see if I can do more with it... is it possible to load an XML serialized file, but completely IGNORE a subtree of the XML file if desired?
Anything is possible if you're willing to change the code that's in there.
eg template <class Archive> void load( Archive & ar, MyConfig & c, const unsigned int version ) { ar >> make_nvp("standard",c.standard); if (some_global_flag_or_whatever) ar >> make_nvp("advanced", c.advanced); else ar.skip("advanced"); // key bit }
Something like the following might be made to work. ar >> c.standard if(flag) ar >> c.advanced else{ Advanced a; // to be thrown away ar >> a } But you would have to start thinking about issues such as tracking. That is if you throw away something that is tracked and referred to somewhere else then it would be a problem. In general, I can't predict the consequences of such code.
The motivation is that I want to "register modules" (in my app) that can read/write their configuration in an XML configuration file. But if the module is not registered, I want to skip that part of the configuration file and move on. I figure since the XML format is like a tree, it might/should be possible to ignore an entire segment of the tree.
Is it possible?
That's what the above would do.
In a related note, the "class_id" bits in xml archives seems to make it difficult for users to hand-edit the XML file... Are these tags required?
In general, we don't include anything in the archive unless it has to be there to recover the data.
thanks, Paul
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users

Hi Robert,
On 23 February 2010 01:13, Robert Ramey
Paul wrote:
Hi,
I use xml_woarchive and xml_wiarchive for reading/writing configuration files.
It seems work work well for me, but now I'd like to see if I can do more with it... is it possible to load an XML serialized file, but completely IGNORE a subtree of the XML file if desired?
Anything is possible if you're willing to change the code that's in there.
I'm concerned about the "class_id" magic that might not be skippable. See below
eg template <class Archive> void load( Archive & ar, MyConfig & c, const unsigned int version ) { ar >> make_nvp("standard",c.standard); if (some_global_flag_or_whatever) ar >> make_nvp("advanced", c.advanced); else ar.skip("advanced"); // key bit }
Something like the following might be made to work.
ar >> c.standard if(flag) ar >> c.advanced else{ Advanced a; // to be thrown away ar >> a }
And what if "Advanced" is part of a module that may not be linked into the app ? The "lite" version doesn't have "Advanced", but the "full" version does. The code above doesn't describe how I was going to achieve that, but basically I was going to delegate the serialization of modules, something like void load(ar, modules, version) { string module_name; ar << module_name; ModuleManager::load_if_possible(config.module, module_name); } So if the module isn't available, then its not possible to deserialize the information, even into a temporary object. The code isn't linked in. I had another look at the basic_oarchive code and an XML archive. As you know, the first time a class is serialized, the tag header will also include a class_id="x" tracking="y" version="z"... but if I need to skip an entire subtree, it may miss that first visitation. If EVERY tag included that information, or at least the class_id number, then I could write a new XML archive that would be able to skip subtrees. By the way, is there a reason why there is no YAML archive format? Why only XML as a human-readable option? Thanks, Paul

The code above doesn't describe how I was going to achieve that, but basically I was going to delegate the serialization of modules, something like
void load(ar, modules, version) { string module_name; ar << module_name; ModuleManager::load_if_possible(config.module, module_name); }
maybe a better option would be to include several archives in one stream.
class header {
typedef std::pair
By the way, is there a reason why there is no YAML archive format? Why only XML as a human-readable option?
Someone started a project to do this, but I don't know what happened to it. Robert Ramey

On 23 February 2010 13:53, Robert Ramey
The code above doesn't describe how I was going to achieve that, but basically I was going to delegate the serialization of modules, something like
void load(ar, modules, version) { string module_name; ar << module_name; ModuleManager::load_if_possible(config.module, module_name); }
maybe a better option would be to include several archives in one stream.
class header { typedef std::pair
module std::list<module> m_list; }; void load(stream s, modules, version){ header h; { xml_archive xa(s); ar >> h; } foreach(module m in h){ xml_archive xa(s); if(m.:module_type is in modules) xar >> ? else // skip ahead in stream }
I like this idea! So the result will look like (eg) 10 XML files all mashed together, with 10 XML headers in the one file? That makes it an invalid XML file, right? Which is ok for my purposes, at the moment. thanks, Paul

On 23 February 2010 16:23, Rutger ter Borg
Paul wrote:
I use xml_woarchive and xml_wiarchive for reading/writing configuration files.
I'd recommend to use Boost.PropertyTree for this, not serialization.
Cheers,
Rutger
I had a look at Boost.PropertyTree, but I find the boost::serialization way of recursing through is more convenient. For example, in the docs you have: BOOST_FOREACH(const std::string &name, m_modules) pt.put("debug.modules.module", name, true); and boost::optional<float> v = pt.get_optional<float>("a.path.to.float.value"); But if my configuration is a tree of arbitrary depth then I'm going to need to implement my own recursion, right? Ditto for custom data types, or arrays of classes with more classes inside or doubles, or optional<double> etc etc. And how do you handle versioning? This is a very important issue, but I don't see this addressed at all. boost::serialization offers a built-in versioning system which works well in general... but it looks like I'd have to roll my own versioning system if I use ptree. It seems to me that ptree is designed only for the most basic of configuration requirements. right? thanks, Paul

Paul wrote:
It seems to me that ptree is designed only for the most basic of configuration requirements. right?
Right, although I think there's some support for recursion (getting a ptree out of a ptree). If you would like edit your configuration files outside your program (or even across programs!), I would be very hesitant to use Boost.Serialization. Cheers, Rutger

On 23 February 2010 17:25, Rutger ter Borg
Paul wrote:
It seems to me that ptree is designed only for the most basic of configuration requirements. right?
Right, although I think there's some support for recursion (getting a ptree out of a ptree). If you would like edit your configuration files outside your program (or even across programs!), I would be very hesitant to use Boost.Serialization.
I agree with you, but in this case editing the configuration file
should only be required as a last resort.
IDEA: We could make the serialization XML format more robust if we
were able to add the tracking and version tag to *every*
participants (3)
-
Paul
-
Robert Ramey
-
Rutger ter Borg