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
Ouvrez la définition DSL. Dans l’Explorateur DSL, cliquez sur le nœud Éditeur.
Dans la fenêtre Propriétés, modifiez la propriété FileExtension. N’incluez pas le « . » initial de l’extension de nom de fichier.
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.
Cette définition DSL a été utilisée pour créer un modèle qui présente l’apparence suivante à l’écran.
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
etperson
.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œudfamilyTreeModel
.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œudsperson
.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œudperson
. 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
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.Dans l’Explorateur DSL, développez Xml Serialization Behavior\Class Data\<classe de domaine>\Element Data.
Vérifiez que is Moniker Key a la valeur
false
pour chaque propriété de domaine.Si la classe de domaine possède une classe de base, répétez la procédure dans cette classe.
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
.Dans l’Explorateur DSL, développez Xml Serialization Behavior\Class Data\<classe de domaine>\Element Data, puis sélectionnez la propriété de domaine.
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
Définissez Is Custom dans le nœud de cette classe sous Xml Serialization Behavior.
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
- 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. |