C++:如何删除 "Cereal" XML 节点?

C++: How to remove "Cereal" XML node?

我想将 C++ 对象(反)序列化为 XML 文件。为此,我使用 Cereal 比 Boost 更轻的库。

所以使用 Cereal documentation,我创建了一个非常简单的 MWE。 因此,在对象定义中使用 Cereal serialize 函数,可以将对象导出到 XML 存档中。

MWE:

#include <string.h>
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <vector>

#include <cereal/archives/xml.hpp>
#include <cereal/types/vector.hpp>

using namespace std;
    
class ClassRectangle 
{
    private:
        /* data */
    public:
        std::string nameClass="Rectangle";
        double length=0.;
        double width=0.;
        vector<double> center={0., 2.};
        
        template <class Archive>
        void serialize( Archive & ar ) const
        {
            ar(  CEREAL_NVP( length )  );
            ar(  CEREAL_NVP( width )  );
            ar(  CEREAL_NVP( center )  );
        }
};

int main(void) 
{ 
    // Beginning of main.
    cout << "(Start)" << endl;
    
    // Save Part.
    ClassRectangle Shape;
    cereal::XMLOutputArchive archive( std::cout );
    archive( cereal::make_nvp(Shape.nameClass, Shape) );

    // End of the main.
    cout << "(End) " << endl;   
    return 0; 
} 
// EoF

这个例子产生:

(Start)
(End) 
<?xml version="1.0" encoding="utf-8"?>
<cereal>
    <Rectangle>
        <length>0</length>
        <width>0</width>
        <center size="dynamic">
            <value0>0</value0>
            <value1>1</value1>
        </center>
    </Rectangle>
</cereal>

到目前为止,一切都很好。但是,在此示例中,Rectangle object/XML 节点在 cereal 节点中。

我的问题是: 我怎样才能删除 <cereal> XML 节点?这将给出以下输出:

<?xml version="1.0" encoding="utf-8"?>
<Rectangle>
    <length>0</length>
    <width>0</width>
    <center size="dynamic">
        <value0>0</value0>
        <value1>1</value1>
    </center>
</Rectangle>

正在查看 source code 谷物,看起来您无法删除根标签。我猜它的存在是因为 cereal 只能处理单个根节点,并且因为您可以将多个值直接序列化到存档中,例如:

ClassRectangle Shape;
cereal::XMLOutputArchive archive( std::cout );
archive( cereal::make_nvp("first node", Shape) );    
archive( cereal::make_nvp("second node", Shape) );

这将打破这个限制。我不确定这是否(或是否)是 rapidxml(基础 xml 库)、xml 规范或其他内容的限制。

Cereal 使用具有该确切名称的根节点来序列化您的数据,但也对其进行反序列化(它检查根节点是否具有预期的名称)。

但是,您可以通过指定

来更改该根节点的名称
CEREAL_XML_STRING_VALUE "MyRootNodeName"

包含 xml 存档 header 之前的宏。但请注意,此名称也必须用于反序列化您的 xml 字符串的应用程序中。


当然,您也可以手动删除(并添加)该根标记作为实际序列化的 post(或预)处理步骤。基本上将所有内容序列化为一个字符串流,只从中取出一个子字符串(从您的 <Rectangle> 节点开始并在其结束标记处停止(如果您只有一个节点,它始终是距末尾的固定偏移量)。