c++中的XML序列化/反序列化

XML serialization/deserialization in C++

本文关键字:反序列化 序列化 XML 中的 c++      更新时间:2023-10-16

我有一组将自己序列化为XML的c++类。漂亮极了。我需要一个反序列化例程来初始化来自XML流的相同类。

我不清楚的是如何解析XML流,使用expat或tinyXML,这是流解析器,以知道将什么XML提供给实例供其使用,以初始化自己。

传统上是怎么做的?解析XML文件并在解析XML时创建适当的类确实很容易但反序列化成员函数是什么样子的呢?

谢谢Reza

您的序列化格式必须包含一个元素,该元素指示被序列化对象的类。例如,可以这样开始每个XML序列化对象:

<object>
    <class>ClassName</class>
    ... object data here
</object>

这意味着你的每一个c++类都必须有一个唯一的字符串名来写在XML中。

使用哪种XML解析器并不重要。反序列化函数必须读取类名并将其映射到实际的类。在最简单的形式中,可以用一长串if语句来完成,当然,如果您愿意,您可以提出更复杂的机制。一旦你知道了这个类,你就可以创建一个空实例,并假设你所有的类都继承自一个基类,然后调用一个fromXML()虚函数,这个虚函数在基类中是纯虚的,并在你所有的子类中实现。fromXML()方法将解析XML树的其余部分,并根据从中读取的数据初始化对象实例。

当您将类序列化为XML时,每个节点必须包含一些标识符,表示它们的运行时类型。对于反序列化,创建一个std::unordered_map,将这些类型标识符映射到每个类型的工厂函数。这将要求工厂函数具有相同的签名,因此您需要从一个公共接口派生所有可序列化的类。根据类型标识符在运行时向下转换工厂函数的返回值。创建setter/getter来访问特定节点类型可以拥有的每个属性和值。

如果您使用DOM解析器,事情可能会简单一些,因为当您遇到一个节点时,您有关于它的所有信息。

使用SAX解析器,您必须创建子节点类并设置属性&每个节点的值。您的XML解析器应该允许回调或虚拟方法,可以被覆盖,以通知新的属性&


或者,如果你不介意花钱,最简单的方法就是让别人为你做这件事。我从来没有使用过代码合成XSD,但它是专为你想做的事情。