I have a set of C++ classes that serialize开发者_如何学JAVA themselves to XML. Nice and dandy. I need to have a deserialize routine to initialize the same classes from XML streams.
What is not clear to me is how does one parse the XML stream, using expat or tinyXML, which are stream parsers to know what XML to feed to an instance for it to use, to initialize itself with.
How is this traditionally done? It is really easy to parse the XML file and create the appropriate classes as XML is being parsed but a deserialize member function, what does that look like?
Thanks Reza
Your serialization format must include an element that indicates the class of the object being serialized. For example, you could start each XML serialized object with this:
<object>
<class>ClassName</class>
... object data here
</object>
This means that each of your C++ classes must be given a unique string name to write in the XML.
It doesn't really matter which XML parser you use. Your deserialize function must read the class name and map it to an actual class. In its simplest form this could be done in a long chain of if statements, but of course you can come up with more elaborate mechanisms if you like. Once you know the class you can create an empty instance and assuming all your classes inherit from a base class then call a fromXML()
virtual function that is pure virtual in the base class and implemented in all your subclasses. The fromXML()
method will parse the rest of the XML tree and initialize the object instance according to data read from it.
When you serialize your classes to XML each node must contain some identifier of what their runtime type is. For deserialization create an std::unordered_map
that maps these type identifiers to factory functions for each type. This will require that the factory functions have the same signature, so you'll need to derive all the serializable classes from a common interface. Downcast the return value of the factory function at runtime depending on the type identifier. Create setters / getters to access each attribute and value a particular node type can have.
If you're using a DOM parser things might be a little easier because you have all the information about a node when you encounter it.
With a SAX parser you'll have to create child node classes and set attributes & values for each node as you come across them. Your XML parser should allow callbacks or virtual methods that can be overriden to be notified of new attributes & nodes as you read through the XML file.
Or, if you don't mind spending the money, the easy way out is to let someone else do the work for you. I've never used Code Synthesis XSD but it is designed exactly for what you're trying to do.
精彩评论