【问题标题】:remove versioning on boost xml serialization删除 boost xml 序列化的版本控制
【发布时间】:2011-06-07 10:09:12
【问题描述】:

我只是找不到从 boost xmlarchives 中删除版本跟踪的方法。

例子

    <Settings class_id="0" tracking_level="0" version="1">
     <px class_id="1" tracking_level="1" version="0" object_id="_0">
      <TestInt>3</TestInt>
      <Resolution class_id="2" tracking_level="0" version="0">
       <x>800</x>
       <y>600</y>
      </Resolution>
      <SomeStuff>0</SomeStuff>
     </px>
    </Settings>

我想要使用 class_id="0" tracking_level="0" version="1" 的东西,因为在这种情况下我只是不需要它并且想要一个简单的干净配置,比如文件

代码

void serialize(Archive & ar, const unsigned int version)
{
  ar & make_nvp("TestInt", TestInt);

  ar & make_nvp("Resolution", resolution);
  ar & make_nvp("SomeStuff", SomeStuff);
}

我找到了boost::serialization::track_never,但无处可用

【问题讨论】:

    标签: xml serialization boost


    【解决方案1】:

    有一个名为boost::archive::no_tracking 的(AFAIK 未记录的)标志,但似乎没有任何效果。也许这是一个错误(至少在 XML 档案中)(见下面的评论):

        boost::archive::xml_oarchive oa{std::cout, boost::archive::no_header | boost::archive::no_tracking}; 
    

    (http://boost.2283326.n4.nabble.com/serialization-removing-excess-XML-tags-td2582827.html)

    示例输出(在顶层和所有项目中仍然有版本和跟踪)。

    <my_carbon class_id="0" tracking_level="0" version="0">
        <number>6</number>
        <symbol>C</symbol>
        <AR_electronegativity class_id="1" tracking_level="0" version="0">
            <has_value>1</has_value>
            <value>2.50000000000000000e+00</value>
        </AR_electronegativity>
        <covalent_radius class_id="2" tracking_level="0" version="0">
            <has_value>1</has_value>
            <value class_id="3" tracking_level="0" version="0">
                <value>7.60000000000000009e-01</value>
            </value>
        </covalent_radius>
    ...
    

    【讨论】:

    • 好的 - 我刚刚看了代码。如果使用 no_tracking 标志,我看到有抑制跟踪的代码。 (oserializer.hpp 和 iserializer.hpp)。但是,该代码被注释掉,有效地禁用了该功能。我将不得不查看 git hub 历史以发现何时/为什么这样做。但是很可能发现它无法以可靠的方式实现。也许它在被注释掉的同时从文档中删除了。现在,我有时间说的就这些了。
    【解决方案2】:

    这里关于“跟踪”有些混淆。

    “跟踪”是指在表中累积指向已在存档中序列化的对象的指针。这允许两次序列化同一对象的存档 - 例如由共享指针引用的对象,仅被序列化一次。在这种情况下,每个对象在第一次被序列化时都被分配了一个“object_id”,这样后续就只需要序列化对象 _id 而不是整个对象。这可以节省很多空间。它还保证通过共享指针序列化的对象在加载时仅重新构成一个对象 - 从而保留原始文件结构。在上面的示例中,您可以看到通过跟踪对象被分配了 object_id = "_0"。当实现级别更改为不使用跟踪时,不会分配 object_id。您可以在示例中看到这一点。实现级别的使用通常只是默认设置。在某些情况下,跟踪非常不方便。考虑如果默认跟踪整数类型的序列化会发生什么。这将毫无价值地添加到档案中。如果真的需要通过指针跟踪整数序列化,最好的办法就是将该整数包装在它自己的类中。

    请注意,这与版本控制完全不同。版本是该代码的程序序列化规范。 IIRC 这也是由类的实现级别设置决定的。

    还有进行序列化的程序版本。这是在存档标题中。这允许即使对于没有类版本的类,也可以使程序更改向后兼容。这可以通过存档中的“no_header”来抑制。请注意创建只写存档的可能性。

    Sooo...我认为该系统正在像宣传的那样工作 - 尽管也许广告可以改进。

    【讨论】:

    • 那么,有什么方法可以不使用,例如在 XML 中,跟踪部分:` tracking_level="0" version="0`?是否必须为每个类使用一些宏使用过吗?或者可以为存档全局设置吗?
    【解决方案3】:

    要删除 xml 存档文件的标题,您可以使用

    boost::archive::xml_iarchive ia(is, boost::archive::no_header);
    

    要禁止显示属性 class_id、tracking_level 和 version,您必须使用

    BOOST_CLASS_IMPLEMENTATION( <type>, boost::serialization::object_serializable )
    BOOST_CLASS_TRACKING( <type>, boost::serialization::track_never )
    

    对于每种类型。这些宏需要按此顺序调用。注:你不能使用

    BOOST_CLASS_VERSION
    

    使用上述宏。

    【讨论】:

      【解决方案4】:

      虽然为时已晚,但我想分享我的发现

      BOOST_CLASS_IMPLEMENTATION(My_class, object_serializable)
      

      成功了。

      【讨论】:

        【解决方案5】:

        尝试使用“no_header”选项创建 iarchive:

        boost::archive::xml_iarchive ia(is, boost::archive::no_header);
        

        【讨论】:

        • 谢谢,这至少有点帮助。 no_tracking 与 no_header 在同一个枚举中,但从我刚刚读到的内容来看,它被 boost 禁用,并作为“失败的实验”留下。我将不得不与其余的一起生活^^
        • 您可以将 xml_archive 从 boost 复制/粘贴到您的项目并进行修改
        猜你喜欢
        • 2017-06-22
        • 2011-03-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-09-14
        • 1970-01-01
        • 2020-08-23
        • 1970-01-01
        相关资源
        最近更新 更多