2009-07-29 5 views
5

J'ai une application qui enregistre des documents (pensez à des documents Word) dans un format XML - Actuellement, les classes C# générées à partir de fichiers xsd sont utilisées pour lire/écrire le format du document et tous était bien jusqu'à récemment quand je devais faire un changement du format du document. Mon souci est la compatibilité ascendante puisque les futures versions de mon application ont besoin de pour pouvoir lire les documents sauvegardés par toutes les versions précédentes et, idéalement, je veux aussi que les anciennes versions de mon application puissent gérer avec élégance les documents lus par les futures versions de mon app.Comment gérer différentes formes incompatibles de documents Xml

Par exemple, en supposant que je change le schéma de mon document pour ajouter un (en option) élément supplémentaire quelque part, puis les anciennes versions de mon application ignoreront simplement le elemnt supplémentaire et il n'y aura pas de problème:

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

Cependant, si une modification de rupture est effectuée (un attribut est changé en un élément, par exemple, ou une collection d'éléments), alors les versions antérieures de mon application devraient soit ignorer cet élément si elle est facultative, soit informer l'utilisateur qu'elles tentent pour lire un document enregistré avec une version plus récente de mon application autrement. Aussi 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é est nécessaire pour lire les deux documents différents.

Un exemple d'un tel changement serait le code XML suivant:

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

Changer à:

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

Afin d'éviter les maux de tête de soutien à l'avenir que je voulais venir avec une vie décente stratégie pour gérer les changements que je pourrais faire à l'avenir, de sorte que les versions de mon application que je publie maintenant vont être en mesure de faire face à ces changements dans le futur:

  • Le "numéro de version" du document doit-il être stocké dans le document lui-même, et si oui, quelle stratégie de versionage doit-on utiliser? 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, une révision majeure indique des changements brusques, alors que des incréments de révision mineurs indiquent des modifications non-brisées - par exemple des éléments facultatifs). méthode dois-je utiliser pour lire le document lui-même et comment puis-je éviter de répliquer des quantités massives de code pour différentes versions de documents?
    • Bien que XPath soit évidemment le plus flexible, c'est beaucoup plus de travail à implémenter que de simplement générer des classes avec xsd. D'autre part, si l'analyse DOM est utilisée, une nouvelle copie du document xsd sera nécessaire dans le contrôle de source pour chaque changement de rupture, ce qui pose des problèmes si des correctifs doivent être appliqués aux anciens schémas (les anciennes versions de l'application toujours supporté).

De plus, je travaille tout cela très loosly sur l'hypothèse que tous les changements que je fais peut être divisé en ces deux catégories de « changements de débecquage » et « changements insécables », mais je suis pas entièrement convaincu que c'est une hypothèse sûre à faire.

Notez que j'utilise le terme "document" de manière très lâche - le contenu ne ressemble en rien à un document!

Merci pour tous les conseils que vous pouvez m'offrir.

Répondre

4

Vous avez certainement besoin d'un numéro de version dans le fichier XML, et je suggère de ne pas le lier à la version de l'application, car il s'agit vraiment d'une entité distincte. Vous pouvez à travers deux ou trois versions de votre application sans jamais changer le format XML ou vous pouvez changer le 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 supprimer des éléments ou en changer le nom. Vous pouvez toujours ajouter des éléments et l'ancien code les ignorera volontiers (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, de sorte que vous ne finissiez pas avec toute une pile de routines d'analyse dans votre code source.

0

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

De cette façon, les anciennes versions ne seront pas brisées, et les versions plus récentes de votre logiciel verront l'attribut et passeront à une méthode de chargement différente.

La numérotation des versions dépend de la fréquence de diffusion. J'irais personnellement avec le numéro de build principal de votre logiciel, sauf si vous prévoyez que le format change plus souvent que cela.

Modifier: juste remarqué le peu de duplication de code:

Pour que je voudrais utiliser le modèle Factory, quelque chose comme ceci:

LoadDocument 
DoNonVersionDependingLoading 
VersionSpecificLoaderFactory(VersionNumber) 
4

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

Vous pouvez appliquer les transformations en séquence jusqu'à ce que vous atteigniez la version actuelle. Ainsi, vous ne modifiez que la dernière version du document. Bien sûr, vous ne pourrez pas enregistrer dans l'ancien format et vous risquez de casser le document pour les anciennes versions, mais cela est typique de nombreuses applications. Si vous devez absolument enregistrer dans l'ancienne version, créez simplement une transformation qui va dans l'autre sens. Comme @Andy dit, utilisez le numéro de build principal de votre application.

+0

Tout à fait d'accord avec ce XSLT est votre ami, de cette façon, vous pouvez créer un XSL qui modifierait simplement le document assez pour obtenir un état connu pour cette version. Vous pourriez avoir des charges pour chaque changement de version puis dans votre contrôle de source vous avez seulement besoin de stocker le XSL avec chaque changement de format similaire à Migrations dans Rudy on Rails –

+3

Je suis d'accord que XSLT est une façon élégante de le faire, mais je ne ferais pas la version du format XML au numéro de version de l'application (voir ma réponse pour mon raisonnement). –

+0

@ 17 of 26 est exact, vous aurez besoin de nouvelles versions pour certains correctifs et pour les versions intermédiaires, et vous n'en aurez pas besoin nécessairement d'une version majeure. – Ishmael

Questions connexes