2011-08-31 4 views
0

J'ai un ensemble de classes C++ qui se sérialisent en XML. Nice et dandy. J'ai besoin d'une routine de désérialisation pour initialiser les mêmes classes à partir des flux XML. Ce qui ne me paraît pas clair, c'est comment analyser le flux XML, en utilisant expat ou tinyXML, qui sont des analyseurs de flux pour savoir ce que XML doit fournir à une instance pour qu'il s'initialise.Sérialisation/désérialisation XML en C++

Comment cela se fait-il traditionnellement? Il est vraiment facile d'analyser le fichier XML et de créer les classes appropriées lorsque XML est analysé, mais une fonction de désérialisation des membres, à quoi cela ressemble-t-il?

Merci Reza

+1

Je ne connais pas "traditionnellement", mais une "usine" me vient à l'esprit. –

Répondre

0

Votre format de sérialisation doit inclure un élément qui indique la classe de l'objet en cours de sérialisation. Par exemple, vous pouvez commencer chaque objet sérialisé XML avec ceci:

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

Cela signifie que chacune de vos classes C++ doit être donné un nom de chaîne unique pour écrire dans le fichier XML.

L'analyseur XML que vous utilisez n'a pas vraiment d'importance. Votre fonction de désérialisation doit lire le nom de la classe et la mapper à une classe réelle. Dans sa forme la plus simple, cela pourrait se faire dans une longue chaîne d'instructions if, mais bien sûr, vous pouvez proposer des mécanismes plus élaborés si vous le souhaitez. Une fois que vous connaissez la classe, vous pouvez créer une instance vide et supposer que toutes vos classes héritent d'une classe de base, puis appelez une fonction virtuelle fromXML() qui est pure virtuelle dans la classe de base et implémentée dans toutes vos sous-classes. La méthode fromXML() analyse le reste de l'arborescence XML et initialise l'instance d'objet en fonction des données lues.

0

Lorsque vous sérialisez vos classes au format XML, chaque noeud doit contenir un identifiant de leur type d'exécution. Pour la désérialisation, créez un std::unordered_map qui mappe ces identificateurs de type aux fonctions d'usine pour chaque type. Cela nécessitera que les fonctions d'usine aient la même signature, vous devrez donc dériver toutes les classes sérialisables à partir d'une interface commune. Diminuer la valeur de retour de la fonction d'usine au moment de l'exécution en fonction de l'identificateur de type. Créer des setters/getters pour accéder à chaque attribut et la valeur d'un type de nœud particulier peut avoir.

Si vous utilisez un parseur DOM, les choses peuvent être un peu plus faciles car vous avez toutes les informations sur un nœud lorsque vous le rencontrez. Avec un analyseur syntaxique SAX, vous devrez créer des classes de nœuds enfants et définir des valeurs & pour chaque nœud lorsque vous les rencontrez. Votre analyseur XML doit autoriser les callbacks ou les méthodes virtuelles pouvant être remplacées à être notifiés des nouveaux attributs & nœuds lors de la lecture du fichier XML. Ou, si cela ne vous dérange pas de dépenser de l'argent, le moyen le plus facile est de laisser quelqu'un d'autre faire le travail pour vous. Je n'ai jamais utilisé Code Synthesis XSD mais il est conçu exactement pour ce que vous essayez de faire.