Question

J'ai une application qui enregistre les documents (documents think word) dans un format basé sur XML - Actuellement, les classes C # générées à partir de fichiers xsd sont utilisées pour lire / écrire le format du document. Tout allait bien jusqu'à récemment, lorsque j'ai dû effectuer une modification. le format du document. Ma préoccupation concerne la compatibilité avec les versions antérieures, car les futures versions de mon application doivent pouvoir lire les documents enregistrés avec toutes les versions précédentes. Idéalement, je souhaite également que les versions antérieures de mon application puissent gérer avec élégance la lecture des documents enregistrés. par les futures versions de mon application.

Par exemple, si je modifie le schéma de mon document pour ajouter un élément supplémentaire (facultatif) quelque part, les anciennes versions de mon application ignoreront simplement l'élément supplémentaire et il n'y aura pas de problèmes:

<doc>
    <!-- Existing document -->
    <myElement>Hello World!</myElement>
</doc>

Cependant, si une modification importante est apportée (un attribut est transformé en un élément par exemple ou en une collection d'éléments), les versions antérieures de mon application doivent alors ignorer cet élément s'il est facultatif ou informer l'utilisateur qu'il tentent de lire un document enregistré avec une version plus récente de mon application sinon. En outre, cela me cause actuellement des maux de tête, car toutes les versions futures de mon application nécessitent un code entièrement séparé pour la lecture des deux documents.

Un exemple d'une telle modification serait le code xml suivant:

<doc>
    <!-- Existing document -->
    <someElement contents="12" />
</doc>

Passage à:

<doc>
    <!-- Existing document -->
    <someElement>
        <contents>12</contents>
        <contents>13</contents>
    </someElement>
</doc>

Afin de prévenir les maux de tête du support technique à l'avenir, je souhaitais proposer une stratégie décente pour gérer les modifications que je pourrais apporter à l'avenir, afin que les versions de mon application que je publie maintenant puissent y faire face. changements à venir:

  • Le & numéro; numéro de version " du document soit stocké dans le document lui-même, et si oui quelle stratégie de version devrait être utilisée? Si la version du document correspond à la version de l'assembly .exe ou si une stratégie plus complexe doit être utilisée (par exemple, révision majeure modifiée, modifications majeures, alors que des incréments de révision mineurs indiquent des modifications intempestives, telles que des éléments optionnels supplémentaires)
  • Quelle méthode dois-je utiliser pour lire le document lui-même et comment éviter de répliquer des quantités énormes de code pour différentes versions de documents?
    • Bien que XPath soit évidemment le plus flexible, sa mise en oeuvre est bien plus complexe que la simple génération de classes avec xsd.
    • D'autre part, si l'analyse DOM est utilisée, une nouvelle copie du document xsd serait nécessaire dans le contrôle de source pour chaque modification importante, ce qui poserait des problèmes si des correctifs devaient être appliqués à des schémas plus anciens (les anciennes versions de l'application sont disponibles). toujours pris en charge).

De plus, j’ai travaillé très vaguement sur l’hypothèse que tous les changements que je faisais peuvent être divisés en ces deux catégories de "changements radicaux". et "des changements inconditionnels", mais je ne suis pas entièrement convaincu que ce soit une hypothèse sûre.

Notez que j'utilise le terme "document". très lâchement - le contenu ne ressemble pas du tout à un document!

Merci pour tout conseil que vous pouvez me donner.

Était-ce utile?

La solution

Vous avez certainement besoin d'un numéro de version dans le fichier XML, et je suggérerais de ne pas le lier à la version de l'application, car il s'agit vraiment d'une entité distincte. Vous pouvez utiliser deux ou trois versions de votre application sans jamais changer le format XML ou vous pouvez éventuellement changer de format plusieurs fois au cours du développement d'une seule version.

Si vous souhaitez que les anciennes versions de l'application puissent lire les versions plus récentes du fichier XML, vous ne pouvez jamais, jamais, supprimer des éléments ou modifier leur nom. Vous pouvez toujours ajouter des éléments et l'ancien code les ignorera volontiers (l'une des fonctionnalités intéressantes de XML), mais si vous les supprimez, l'ancien code ne pourra plus fonctionner.

Comme Ishmael l'a dit, XSLT est un bon moyen de convertir le format XML d'une version à une autre afin d'éviter toute pile de routines d'analyse dans votre code source.

Autres conseils

XSLT est un choix évident ici. Étant donné que vous pouvez identifier la version de votre document, créez pour chaque version de votre schéma un XSLT transformant la version précédente en votre nouvelle version.

Vous pouvez appliquer les transformations en séquence jusqu'à atteindre la version actuelle. Ainsi, vous ne modifiez jamais que la dernière version du document. Bien sûr, vous ne pourrez pas enregistrer dans l'ancien format et vous pourrez casser le document d'anciennes versions, mais ceci est typique de nombreuses applications. Si vous avez absolument besoin de sauvegarder dans l'ancienne version, créez simplement une transformation dans l'autre sens.

Comme @Andy le dit, utilisez le numéro de version principale de votre application.

Pourriez-vous ajouter un attribut à l'élément racine spécifiant la version?

Ainsi, les anciennes versions ne seront pas endommagées et les versions plus récentes de votre logiciel verront l'attribut et basculeront de manière appropriée vers une méthode de chargement différente.

La numérotation des versions dépendrait de votre fréquence de publication. Personnellement, je choisirais le numéro de version majeure de votre logiciel, à moins que vous ne prévoyiez que le format change plus souvent.

Modifier : vous venez de remarquer le problème de la duplication de code:

Pour cela, je voudrais utiliser le modèle d'usine, quelque chose comme ceci:

LoadDocument
DoNonVersionDependingLoading
VersionSpecificLoaderFactory(VersionNumber)
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top