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>
节点开始并在其结束标记处停止(如果您只有一个节点,它始终是距末尾的固定偏移量)。
我想将 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>
节点开始并在其结束标记处停止(如果您只有一个节点,它始终是距末尾的固定偏移量)。