Partager via


Personnaliser le stockage de fichiers et la sérialisation XML

Lorsque l’utilisateur enregistre une instance, ou un modèle, d’un langage dédié (DSL) dans Visual Studio, un fichier XML est créé ou mis à jour. Ce fichier peut être rechargé pour recréer le modèle dans le Store.

Vous pouvez personnaliser le schéma de sérialisation en ajustant les paramètres sous Xml Serialization Behavior dans l’Explorateur DSL. Il existe un nœud sous Xml Serialization Behavior pour chaque classe de domaine, chaque propriété et chaque relation. Les relations se trouvent dans leur classe source. Il existe également des nœuds correspondant aux classes de forme, de connecteur et de diagramme.

Vous pouvez aussi écrire du code de programme pour une personnalisation plus avancée.

Notes

Si vous souhaitez enregistrer le modèle dans un format particulier, mais que vous n’avez pas besoin de le recharger sous cette forme, vous pouvez utiliser des modèles de texte pour générer la sortie du modèle, au lieu d’un schéma de sérialisation personnalisé. Pour plus d’informations, consultez Génération de code à partir d’un langage dédié.

Fichiers de modèle et de diagramme

Chaque modèle est généralement enregistré dans deux fichiers :

  • Le fichier de modèle porte un nom du type Model1.mydsl. Il stocke les éléments de modèle et les relations, ainsi que leurs propriétés. L’extension de fichier (par exemple .mydsl) est déterminée par la propriété FileExtension du nœud Editor dans la définition DSL.

  • Le fichier de diagramme porte un nom du type Model1.mydsl.diagram. Il stocke les formes, les connecteurs et leurs positions, les couleurs, les épaisseurs de trait et d’autres informations sur l’apparence du diagramme. Si l’utilisateur supprime un fichier .diagram, les informations essentielles dans le modèle ne sont pas perdues. Seule la disposition du diagramme l’est. Lorsque le fichier de modèle est ouvert, un ensemble par défaut de formes et de connecteurs est créé.

Modification de l’extension de fichier d’une définition DSL

  1. Ouvrez la définition DSL. Dans l’Explorateur DSL, cliquez sur le nœud Éditeur.

  2. Dans la fenêtre Propriétés, modifiez la propriété FileExtension. N’incluez pas le « . » initial de l’extension de nom de fichier.

  3. Dans l’Explorateur de solutions, modifiez le nom des deux fichiers de modèle d’élément dans DslPackage\ProjectItemTemplates. Ces fichiers portent des noms conformes au format suivant :

    myDsl.diagram

    myDsl.myDsl

Schéma de sérialisation par défaut

La définition DSL utilisée pour créer un exemple dans cette rubrique est la suivante.

DSL Definition diagram - family tree model

Cette définition DSL a été utilisée pour créer un modèle qui présente l’apparence suivante à l’écran.

Family tree diagram, toolbox, and explorer

Ce modèle a été enregistré, puis rouvert dans l’éditeur de texte XML :

<?xml version="1.0" encoding="utf-8"?>
<familyTreeModel xmlns:dm0="http://schemas.microsoft.com/VisualStudio/2008/DslTools/Core" dslVersion="1.0.0.0" Id="f817b728-e920-458e-bb99-98edc469d78f" xmlns="http://schemas.microsoft.com/dsltools/FamilyTree">
  <people>
    <person name="Henry VIII" birthYear="1491" deathYear="1547" age="519">
      <children>
        <personMoniker name="/f817b728-e920-458e-bb99-98edc469d78f/Elizabeth I" />
        <personMoniker name="/f817b728-e920-458e-bb99-98edc469d78f/Mary" />
      </children>
    </person>
    <person name="Elizabeth I" birthYear="1533" deathYear="1603" age="477" />
    <person name="Mary" birthYear="1515" deathYear="1558" age="495" />
  </people>
</familyTreeModel>

Notez les points suivants concernant le modèle sérialisé :

  • Chaque nœud XML porte un nom identique à un nom de classe de domaine, à ceci près que la lettre initiale est en minuscules. Par exemple : familyTreeModel et person.

  • Les propriétés de domaine telles que Name et BirthYear sont sérialisées sous forme d’attributs dans les nœuds XML. Là encore, le caractère initial du nom de propriété est converti en minuscules.

  • Chaque relation est sérialisée sous la forme d’un nœud XML imbriqué à l’intérieur de l’extrémité source de la relation. Le nœud porte le même nom que la propriété de rôle source, mais avec un caractère initial en minuscules.

    Par exemple, un rôle nommé People dans la définition DSL provient de la classe FamilyTree. Dans le code XML, cela est représenté par le nœud nommé people imbriqué à l’intérieur du nœud familyTreeModel.

  • L’extrémité cible de chaque imbrication de la relation est sérialisée sous la forme d’un nœud imbriqué sous la relation. Par exemple, le nœud people contient plusieurs nœuds person.

  • L’extrémité cible de chaque relation de référence est sérialisée sous forme de moniker, qui encode une référence à l’élément cible.

    Par exemple, il peut y avoir une relation children sous un nœud person. Ce nœud contient différents monikers :

    <personMoniker name="/f817b728-e920-458e-bb99-98edc469d78f/Elizabeth I" />
    

Présentation des monikers

Les monikers permettent de représenter des références croisées entre différentes parties des fichiers de modèle et de diagramme. Ils sont également utilisés dans le fichier .diagram pour faire référence aux nœuds dans le fichier de modèle. Il existe deux formes de monikers :

  • Les monikers d’ID citent le GUID de l’élément cible. Par exemple :

    <personShapeMoniker Id="f79734c0-3da1-4d72-9514-848fa9e75157" />
    
  • Les monikers de clé qualifiés identifient l’élément cible par la valeur d’une propriété de domaine désignée appelée clé de moniker. Le moniker de l’élément cible est préfixé par le moniker de son élément parent dans l’arborescence des imbrications de la relation.

    Les exemples suivants sont tirés d’une définition DSL dans laquelle il existe une classe de domaine nommée Album, qui présente une imbrication de la relation avec une classe de domaine nommée Song :

    <albumMoniker title="/My Favorites/Jazz after Teatime" />
    <songMoniker title="/My Favorites/Jazz after Teatime/Hot tea" />
    

    Des monikers de clé qualifiés sont utilisés si la classe cible présente une propriété de domaine pour laquelle l’option Is Moniker Key est définie sur true dans Xml Serialization Behavior. Dans l’exemple, cette option est définie pour les propriétés de domaine nommées « Title » dans les classes de domaine « Album » et « Song ».

Les monikers de clé qualifiés sont plus faciles à lire que les monikers d’ID. Si vous souhaitez que le code XML de vos fichiers de modèle soit lu par des gens, privilégiez les monikers de clé qualifiés. Toutefois, il est possible pour l’utilisateur de définir plusieurs éléments possédant la même clé de moniker. Les doublons de clés peuvent empêcher le rechargement du fichier. Par conséquent, si vous définissez une classe de domaine à laquelle font référence des monikers de clé qualifiés, vous devez envisager des moyens d’empêcher l’utilisateur d’enregistrer un fichier contenant des monikers en double.

Définition d’une classe de domaine à laquelle feront référence des monikers d’ID

  1. Assurez-vous que Is Moniker Key a la valeur false pour chacune des propriétés de domaine de la classe et de ses classes de base.

    1. Dans l’Explorateur DSL, développez Xml Serialization Behavior\Class Data\<classe de domaine>\Element Data.

    2. Vérifiez que is Moniker Key a la valeur false pour chaque propriété de domaine.

    3. Si la classe de domaine possède une classe de base, répétez la procédure dans cette classe.

  2. Définissez la propriété Serialize Id = true de la classe de domaine.

    Cette propriété se trouve sous Xml Serialization Behavior.

Définition d’une classe de domaine à laquelle feront référence des monikers de clé qualifiés

  • Définissez Is Moniker Key pour une propriété de domaine d’une classe de domaine existante. Le type de la propriété doit être string.

    1. Dans l’Explorateur DSL, développez Xml Serialization Behavior\Class Data\<classe de domaine>\Element Data, puis sélectionnez la propriété de domaine.

    2. Dans la fenêtre Propriétés, définissez Is Moniker Key sur true.

  • - ou -

    Créez une classe de domaine à l’aide de l’outil Classe de domaine nommée.

    Cet outil crée une classe qui possède une propriété de domaine nommée Name. Les propriétés Is Element Name et Is Moniker Key de cette propriété de domaine sont initialisées à la valeur true.

  • - ou -

    Créez une relation d’héritage de la classe de domaine vers une autre classe possédant une propriété de clé de moniker.

Prévention des doublons de monikers

Si vous utilisez des monikers de clé qualifiés, il est possible que deux éléments du modèle d’un utilisateur prennent la même valeur dans la propriété de clé. Dans le cas, par exemple, d’une définition DSL comportant une classe Person qui possède une propriété Name, l’utilisateur peut définir une valeur Name identique pour deux éléments. Bien que le modèle puisse être enregistré dans un fichier, il ne se recharge pas correctement.

Plusieurs méthodes permettent d’éviter cette situation :

  • Définissez Is Element Name = true de la propriété de domaine de clé. Sélectionnez la propriété de domaine dans le diagramme Définition DSL, puis choisissez sa valeur dans la fenêtre Propriétés.

    Lorsque l’utilisateur crée une instance de la classe, cette valeur entraîne l’attribution automatique d’une valeur différente à la propriété de domaine. Le comportement par défaut consiste à ajouter un chiffre à la fin du nom de la classe. Rien n’empêche l’utilisateur de remplacer ce nom par un doublon, mais ce système reste utile dans le cas où l’utilisateur ne définit pas la valeur avant d’enregistrer le modèle.

  • Activez la validation pour la définition DSL. Dans l’Explorateur DSL, sélectionnez Editor\Validation, puis définissez les propriétés Utilise… sur true.

    Il existe une méthode de validation générée automatiquement qui recherche les ambiguïtés. Elle se trouve dans la catégorie de validation Load. L’utilisateur est ainsi averti qu’il ne sera peut-être pas possible de rouvrir le fichier.

    Pour plus d’informations, consultez Validation dans un langage dédié.

Chemins et qualificateurs de monikers

Un moniker de clé qualifié se termine par la clé de moniker et est préfixé par le moniker de son parent dans l’arborescence d’incorporation. Prenons par exemple le moniker d’un Album :

<albumMoniker title="/My Favorites/Jazz after Teatime" />

L’une des chansons (Song) de cet Album peut alors être la suivante :

<songMoniker title="/My Favorites/Jazz after Teatime/Hot tea" />

Si toutefois il est fait référence aux Albums par leur ID, les monikers sont les suivants :

<albumMoniker Id="77472c3a-9bf9-4085-976a-d97a4745237c" />
<songMoniker title="/77472c3a-9bf9-4085-976a-d97a4745237c/Hot tea" />

Notez que, un GUID étant unique, il n’est jamais préfixé par le moniker de son parent.

Si vous savez qu’une propriété de domaine en particulier possédera toujours une valeur unique dans un modèle, vous pouvez définir Is Moniker Qualifier sur true pour cette propriété. Elle sera donc utilisée comme qualificateur, sans le moniker du parent. Dans le cas par exemple où à la fois Is Moniker Qualifier et Is Moniker Key sont définis pour la propriété de domaine Title de la classe Album, le nom ou l’identificateur du modèle n’est pas employé dans les monikers de la classe Album ni de ses enfants incorporés :

<albumMoniker name="Jazz after Teatime" />
<songMoniker title="/Jazz after Teatime/Hot tea" />

Personnalisation de la structure XML

Pour effectuer les personnalisations suivantes, développez le nœud Xml Serialization Behavior dans l’Explorateur DSL. Sous une classe de domaine, développez le nœud Element Data pour afficher la liste des propriétés et relations issues de cette classe. Sélectionnez une relation et ajustez ses options dans la fenêtre Propriétés.

  • Définissez Omit Element sur true pour omettre le nœud de rôle source, en laissant uniquement la liste des éléments cibles. Ne définissez pas cette option s’il existe plusieurs relations entre les classes source et cible.

    <familyTreeModel ...>
      <!-- The following node is omitted by using Omit Element: -->
      <!-- <people> -->
        <person name="Henry VIII" .../>
        <person name="Elizabeth I" .../>
      <!-- </people> -->
    </familyTreeModel>
    
  • Définissez Use Full Form pour incorporer les nœuds cibles dans des nœuds représentant les instances de relation. Cette option est définie automatiquement lorsque des propriétés de domaine sont ajoutées à une relation de domaine.

    <familyTreeModel ...>
      <people>
        <!-- The following node is inserted by using Use Full Form: -->
        <familyTreeModelHasPeople myRelationshipProperty="x1">
          <person name="Henry VIII" .../>
        </familyTreeModelHasPeople>
        <familyTreeModelHasPeople myRelationshipProperty="x2">
          <person name="Elizabeth I" .../>
        </familyTreeModelHasPeople>
      </people>
    </familyTreeModel>
    
  • Définissez Representation = Element pour qu’une propriété de domaine soit enregistrée en tant qu’élément plutôt qu’en tant que valeur d’attribut.

    <person name="Elizabeth I" birthYear="1533">
      <deathYear>1603</deathYear>
    </person>
    
  • Pour modifier l’ordre dans lequel les attributs et les relations sont sérialisés, cliquez avec le bouton droit sur un élément sous Element Data, puis utilisez les commandes de menu Monter et Descendre.

Personnalisation majeure à l’aide du code du programme

Vous pouvez remplacer une partie ou la totalité des algorithmes de sérialisation.

Nous vous recommandons d’étudier le code qui se trouve dans Dsl\Generated Code\Serializer.cs et SerializationHelper.cs.

Personnalisation de la sérialisation d’une classe en particulier

  1. Définissez Is Custom dans le nœud de cette classe sous Xml Serialization Behavior.

  2. Transformez tous les modèles, générez la solution et examinez les erreurs de compilation qui en résultent. Les commentaires situés à côté de chaque erreur expliquent le code à fournir.

Spécification d’une sérialisation personnalisée pour l’ensemble du modèle

  1. Remplacez les méthodes présentes dans Dsl\GeneratedCode\SerializationHelper.cs.

Options de Xml Serialization Behavior

Dans l’Explorateur DSL, le nœud Xml Serialization Behavior contient un nœud enfant pour chaque classe de domaine, relation, forme, connecteur et classe de diagramme. Sous chacun de ces nœuds se trouve la liste des propriétés et relations sources figurant sur cet élément. Les relations sont représentées à la fois en tant que telles et sous leurs classes sources.

Le tableau suivant récapitule les options disponibles dans cette section de la définition DSL. Dans chaque cas, sélectionnez un élément dans l’Explorateur DSL et définissez les options dans la fenêtre Propriétés.

Xml Class data

Ces éléments se trouvent dans l’Explorateur DSL sous Xml Serialization Behavior\Class Data.

Propriété Description
Has Custom Element Schema Si la valeur est true, indique que la classe de domaine possède un schéma d’élément personnalisé.
Is Custom Si la valeur est true, indique que vous souhaitez écrire votre propre code de sérialisation et de désérialisation pour cette classe de domaine.

Générez la solution et examinez les erreurs pour obtenir des instructions détaillées.
Classe de domaine Classe de domaine à laquelle ce nœud de données de classe s’applique. Lecture seule.
Nom de l’élément Nom de nœud XML des éléments de cette classe. La valeur par défaut est une version minuscule du nom de la classe de domaine.
Nom de l’attribut du moniker Nom de l’attribut utilisé dans les éléments du moniker pour contenir la référence. Si vide, le nom de la propriété ou l'identificateur de clé est utilisé.

Dans cet exemple, il s’agit de "name": <personMoniker name="/Mike Nash"/>.
Nom de l’élément du moniker Nom de l’élément XML utilisé pour les monikers qui font référence aux éléments de cette classe.

La valeur par défaut est une version minuscule du nom de la classe avec le suffixe « Moniker ». Par exemple : personMoniker.
Nom du type de moniker Nom du type XSD généré pour les monikers aux éléments de cette classe. Le XSD se trouve dans Dsl\Generated Code\*Schema.xsd.
Serialize Id Si la valeur est true, indique que le GUID de l’élément est inclus dans le fichier. Cette propriété doit être true s’il n’existe aucune propriété marquée Is Moniker Key et si la définition DSL spécifie les relations de référence à cette classe.
Nom de type Nom du type XML généré dans XSD à partir de la classe de domaine indiquée.
Notes Notes informelles associées à cet élément.

Données des propriétés XML

Les nœuds de propriété XML se trouvent sous les nœuds de classe.

Propriété Description
Propriété de domaine Propriété à laquelle les données de configuration de sérialisation XML s'appliquent. Lecture seule.
Is Moniker Key Si la valeur est true, indique que la propriété est utilisée comme clé pour créer des monikers qui font référence à des instances de cette classe de domaine.
Is Moniker Qualifier Si la valeur est True, la propriété est utilisée pour créer le qualificateur dans les monikers. Si la valeur est false et si Serialize Id n’est pas true pour cette classe de domaine, les monikers sont qualifiés par le moniker de l’élément parent dans l’arborescence d’incorporation.
Représentation Si Attribute, la propriété est sérialisée en tant qu'attribut XML ; si Element, elle est sérialisée en tant qu'élément ; si Ignore, elle n'est pas sérialisée.
Nom XML Nom utilisé pour l'attribut ou l'élément XML représentant la propriété. Par défaut, il s’agit d’une version minuscule du nom de la propriété de domaine.
Notes Notes informelles associées à cet élément.

Données de rôle XML

Les nœuds de données de rôle se trouvent sous les nœuds de classe source.

Propriété Description
Has Custom Moniker Si la valeur est true, indique que vous souhaitez fournir votre propre code pour générer et résoudre les monikers qui traversent cette relation.

Pour obtenir des instructions détaillées, générez la solution, puis double-cliquez sur les messages d’erreur.
Relation de domaine Spécifie la relation à laquelle ces options s’appliquent. Lecture seule.
Omit Element Si la valeur est true, indique que la balise XML correspondant au rôle source est omise dans le schéma.

S’il existe plusieurs relations entre les classes source et cible, ce nœud de rôle fait la distinction entre les liens qui appartiennent aux deux relations. Nous vous recommandons donc de ne pas définir cette option dans ce cas.
Nom de l’élément de rôle Spécifie le nom de l’élément XML dérivé du rôle source. La valeur par défaut est le nom de la propriété de rôle.
Use Full Form Si la valeur est true, indique que chaque élément ou moniker cible est placé dans un nœud XML représentant la relation. Cette propriété doit être true si la relation possède ses propres propriétés de domaine.