用于增强序列化的与订单无关的输入存档

时间:2015-09-11 10:31:50

标签: c++ xml boost boost-serialization

我使用boost :: serialization非常喜欢它。有时我唯一想念的是,当我想从xml存档中读取配置输入结构时。如果

,那就太好了
  1. xml结构可以是与顺序无关的
  2. 如果xml中缺少对象,则将采用该类的默认值。
  3. 这主要适用于boost :: serialization还是已经有解决方案?

3 个答案:

答案 0 :(得分:1)

因为我觉得展示更具建设性 - 不要说,这里有一个我认为你在使用Boost Property Tree后的样本:

<强> Live On Coliru

#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>

struct Config {
    std::string order;
    double independent;
    std::string stuff;

    static Config load_xml(std::istream& from) {
        boost::property_tree::ptree pt;
        read_xml(from, pt);

        return {
            pt.get("order", "default property value for order"),
            pt.get("independent", 42.0),
            pt.get("stuff", "no stuff configured")
        };
    }

    void save_xml(std::ostream& to) const {
        boost::property_tree::ptree pt;

        if (!order.empty())   pt.put("order",       order);
        if (independent != 0) pt.put("independent", independent);
        if (!stuff.empty())   pt.put("stuff",       stuff);

        write_xml(to, pt);
    }
};

#include <iostream>

int main() {
    {
        Config cfg { "order", 999, "stuff" };
        cfg.save_xml(std::cout);
    }

    std::istringstream iss("<independent>3.1415926535897931</independent><IGNORED>stuff</IGNORED><order>LOOK MA</order>");

    Config::load_xml(iss).save_xml(std::cout);
}

打印哪些:

<?xml version="1.0" encoding="utf-8"?>
<order>order</order><independent>999</independent><stuff>stuff</stuff>
<?xml version="1.0" encoding="utf-8"?>
<order>LOOK MA</order><independent>3.1415926535897931</independent><stuff>no stuff configured</stuff>

答案 1 :(得分:0)

序列化不是为了这个。

当然,无论如何,您都可以将序列化顺序排列的事物做成:

#include <boost/serialization/map.hpp>

struct MyConfig {
    std::map<std::string, std::string> values;

    template<typename Ar> void serialize(Ar& ar, unsigned) {
        ar & values;
    }
};

阅读事物的顺序无关紧要。

此外,您可以选择使用默认值(提示:它根本与序列化无关):

struct MyConfig {
    std::string const& workingDirectory() {
        return *values.emplace("workingdir", "$HOME").first;
    }

  private:
    std::unordered_map<std::string, std::string> values;
};

此处workingDirectory()将返回对反序列化值的引用。如果不存在这样的值,将首先插入"$HOME"

无论其

您应该考虑在此方案中使用Boost Property Tree。它更适合此目的。

答案 2 :(得分:0)

here是我的实验性boost :: serialization存档,可以序列化为boost :: property_tree。

默认情况下,生成的ptree是以适合json或info格式的方式创建的,但很少有修改可以针对xml进行优化。

它可以按任意顺序加载字段,也会忽略其他字段(这允许一些向前兼容性)。

目前错过的字段会产生错误。引入带有默认值的可选字段需要一些额外的工作。

xml存档还有patch允许跳过未知字段,但不允许任意顺序或可选字段。