Sdílet prostřednictvím


Přizpůsobení úložiště souborů a serializace XML

Když uživatel uloží instanci nebo model jazyka specifického pro doménu (DSL) v sadě Visual Studio, vytvoří se nebo aktualizuje soubor XML. Soubor je možné znovu načíst a znovu vytvořit model ve Storu.

Schéma serializace můžete přizpůsobit úpravou nastavení v části Chování serializace XML v Dsl Exploreru. Existuje uzel v části Chování serializace XML pro každou třídu domény, vlastnost a relaci. Relace jsou umístěny v rámci jejich zdrojových tříd. Existují také uzly odpovídající třídám obrazce, spojnice a diagramu.

Můžete také napsat kód programu pro pokročilejší přizpůsobení.

Poznámka:

Pokud chcete model uložit v určitém formátu, ale nepotřebujete ho z tohoto formuláře znovu načíst, zvažte použití textových šablon k vygenerování výstupu z modelu místo vlastního schématu serializace. Další informace naleznete v tématu Generování kódu z jazyka specifického pro doménu.

Soubory modelů a diagramů

Každý model je uložený ve dvou souborech:

  • Soubor modelu má název, například Model1.mydsl. Ukládá prvky modelu a vztahy a jejich vlastnosti. Přípona souboru, jako .mydsl je určena FileExtension vlastnost Editor node v DEFINICi DSL.

  • Soubor diagramu má například název Model1.mydsl.diagram. Ukládá obrazce, spojnice a jejich pozice, barvy, tloušťky čáry a další podrobnosti o vzhledu diagramu. Pokud uživatel odstraní .diagram soubor, základní informace v modelu se neztratí. Ztratí se jenom rozložení diagramu. Při otevření souboru modelu se vytvoří výchozí sada obrazců a spojnic.

Změna přípony souboru DSL

  1. Otevřete definici DSL. V Průzkumníku DSL klikněte na uzel Editor.

  2. V okno Vlastnosti upravte FileExtension vlastnost. Nezahrnujte počáteční příponu . názvu souboru.

  3. V Průzkumník řešení změňte název dvou souborů šablony položky v DslPackage\ProjectItemTemplates. Tyto soubory mají názvy, které mají tento formát:

    myDsl.diagram

    myDsl.myDsl

Výchozí schéma serializace

K vytvoření příkladu pro toto téma se použila následující definice DSL.

Diagram definice DSL – model rodinného stromu

Tento DSL byl použit k vytvoření modelu, který má následující vzhled na obrazovce.

Diagram rodinného stromu, sada nástrojů a průzkumník

Tento model byl uložen a znovu otevřen v textovém editoru 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>

Všimněte si následujících bodů o serializovaném modelu:

  • Každý uzel XML má název, který je stejný jako název třídy domény, s tím rozdílem, že počáteční písmeno je malými písmeny. Příklad: familyTreeModel a person.

  • Vlastnosti domény, jako je Name a BirthYear, jsou serializovány jako atributy v uzlech XML. Znovu se počáteční znak názvu vlastnosti převede na malá písmena.

  • Každá relace je serializována jako uzel XML vnořený uvnitř zdrojového konce relace. Uzel má stejný název jako vlastnost zdrojové role, ale s počátečním znakem malého písmena.

    Například v definici DSL je role, která má název Lidé , zdroj ve třídě FamilyTree . Ve formátu XML je role Lidé reprezentována uzlem vnořeným people uvnitř familyTreeModel uzlu.

  • Cílový konec každé relace vložení je serializován jako uzel vnořený pod relací. Uzel například people obsahuje několik person uzlů.

  • Cílový konec každé relace odkazu je serializován jako moniker, který kóduje odkaz na cílový prvek.

    Například pod person uzlem může existovat children relace. Tento uzel obsahuje například:

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

Principy monikers

Monikers se používají k reprezentaci křížových odkazů mezi různými částmi modelu a soubory diagramu. Používají se také v .diagram souboru k odkazování na uzly v souboru modelu. Existují dvě formy monikeru:

  • ID monikers uvozovat IDENTIFIKÁTOR GUID cílového prvku. Příklad:

    <personShapeMoniker Id="f79734c0-3da1-4d72-9514-848fa9e75157" />
    
  • Kvalifikované klíčové monikery identifikují cílový prvek hodnotou určené vlastnosti domény s názvem moniker key. Moniker cílového prvku je předpona moniker jeho nadřazeného prvku ve stromu vkládání relací.

    Následující příklady pocházejí z DSL, ve kterém je doménová třída s názvem Album, která má vztah vložení do doménové třídy s názvem Song:

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

    Kvalifikovaný klíč monikers se používá, pokud cílová třída má vlastnost domény, pro kterou je možnost Je Moniker Key je nastavena na true xml serializace chování. V tomto příkladu je tato možnost nastavena pro vlastnosti domény s názvem "Title" ve třídách domény Album a Song.

Kvalifikované klíčové monikery jsou čitelnější než id monikers. Pokud máte v úmyslu, aby soubory modelu byly čitelné pro člověka, zvažte použití kvalifikovaných klíčových monikerů. Je však možné, aby uživatel nastavil více než jeden prvek, aby měl stejný klíč monikeru. Duplicitní klíče můžou způsobit, že se soubor nenačte správně. Proto pokud definujete třídu domény, na kterou se odkazuje pomocí kvalifikovaných klíčových monikers, měli byste zvážit způsoby, jak zabránit uživateli v uložení souboru, který má duplicitní monikers.

Nastavení třídy domény, na kterou odkazuje id monikers

  1. Ujistěte se, že je Moniker Key false pro každou vlastnost domény ve třídě a její základní třídy.

    1. V DSL Explorer rozbalte Xml Serialization Behavior\Class Data\<the domain class>\Element Data.

    2. Ověřte, že je false klíč Monikeru pro každou vlastnost domény.

    3. Pokud má doménová třída základní třídu, opakujte proceduru v této třídě.

  2. Nastavte Serializovat ID = true pro třídu domény.

    Tuto vlastnost naleznete v části Xml Serializace Chování.

Nastavení třídy domény tak, aby na ni odkazoval kvalifikovaný klíč

  • Set Is Moniker Key pro vlastnost domény existující třídy domény. Typ vlastnosti musí být string.

    1. V DSL Explorer, rozbalte Xml Serialization Behavior\Class Data\<the domain class>\Element Data a pak vyberte vlastnost domény.

    2. V okno Vlastnosti nastavte Hodnotu Moniker Key na truehodnotu .

  • - nebo -

    Vytvořte novou třídu domény pomocí nástroje Pojmenovaná třída domény .

    Tento nástroj vytvoří novou třídu, která má vlastnost domény s názvem Name. Is Element Name a Is Moniker Key vlastnosti této vlastnosti domény jsou inicializovány na true.

  • - nebo -

    Vytvořte vztah dědičnosti z doménové třídy do jiné třídy, která má vlastnost moniker key.

Vyhněte se duplicitním monikerům

Pokud použijete monikers kvalifikovaného klíče, je možné, že dva prvky v modelu uživatele mohou mít stejnou hodnotu ve vlastnosti klíče. Pokud má například dsl třídu Person, která má vlastnost Jméno, může uživatel nastavit Názvy dvou prvků na stejné. I když by se model dal uložit do souboru, nenačte se správně.

Existuje několik metod, které pomáhají předejít této situaci:

  • Set Is Název = true elementu pro vlastnost domény klíče. Vyberte vlastnost domény v diagramu definice DSL a pak nastavte hodnotu v okno Vlastnosti.

    Když uživatel vytvoří novou instanci třídy, tato hodnota způsobí, že vlastnost domény bude automaticky přiřazena jinou hodnotu. Výchozí chování přidá číslo na konec názvu třídy. To uživateli nezabrání v tom, aby změnil jméno na duplicitní, ale v případě, že uživatel nenastaví hodnotu před uložením modelu.

  • Povolte ověřování pro DSL. V DSL Exploreru vyberte Editor\Validation a nastavte vlastnosti Použití... na truehodnotu .

    Existuje automaticky generovaná metoda ověřování, která kontroluje nejednoznačnosti. Metoda je v Load kategorii ověřování. Tím se zajistí, že se uživateli zobrazí upozornění, že nemusí být možné soubor znovu otevřít.

    Další informace naleznete v tématu Ověřování v jazyce specifickém pro doménu.

Cesty a kvalifikátory moniker

Kvalifikovaný moniker klíče končí klíčem monikeru a má předponu moniker nadřazeného objektu ve stromu vkládání. Pokud je například moniker alba:

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

Pak může být jedna z skladeb v tom albu:

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

Pokud jsou ale alba odkazována podle ID, bude monikers následující:

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

Všimněte si, že protože identifikátor GUID je jedinečný, není nikdy předponou moniker jeho nadřazeného objektu.

Pokud víte, že konkrétní vlastnost domény bude mít vždy jedinečnou hodnotu v rámci modelu, můžete pro tuto vlastnost nastavit kvalifikátor true Is Moniker. To způsobí, že se použije jako kvalifikátor bez použití monikeru nadřazeného objektu. Pokud například nastavíte kvalifikátor Is Moniker a Is Moniker Key pro vlastnost Název domény třídy Album, název nebo identifikátor modelu se v monikers pro Album a jeho vložené podřízené položky nepoužívá:

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

Přizpůsobení struktury XML

Chcete-li provést následující přizpůsobení, rozbalte uzel Chování serializace XML v DSL Exploreru. V rámci třídy domény rozbalte uzel Data elementu a zobrazte seznam vlastností a relací, které jsou zdrojové v této třídě. Vyberte relaci a upravte její možnosti v okno Vlastnosti.

  • Nastavte vynechání elementu na hodnotu true, pokud chcete vynechat zdrojový uzel role a ponechat pouze seznam cílových elementů. Tuto možnost byste neměli nastavit, pokud mezi zdrojovými a cílovými třídami existuje více než jeden vztah.

    <familyTreeModel ...>
      <!-- The following node is omitted by using Omit Element: -->
      <!-- <people> -->
        <person name="Henry VIII" .../>
        <person name="Elizabeth I" .../>
      <!-- </people> -->
    </familyTreeModel>
    
  • Pokud chcete vložit cílové uzly do uzlů představujících instance relací, nastavte možnost Použít úplný formulář . Tato možnost se nastaví automaticky při přidání vlastností domény do vztahu domény.

    <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>
    
  • Nastavit Representation = Element mít vlastnost domény uložena jako element místo jako atribut hodnota.

    <person name="Elizabeth I" birthYear="1533">
      <deathYear>1603</deathYear>
    </person>
    
  • Chcete-li změnit pořadí, ve kterém jsou atributy a relace serializovány, klikněte pravým tlačítkem myši na položku v části Data elementu a použijte příkazy nabídky Přesunout nahoru nebo Přesunout dolů .

Hlavní přizpůsobení pomocí kódu programu

Můžete nahradit části nebo všechny algoritmy serializace.

Doporučujeme studovat kód v Dsl\Generated Code\Serializer.cs a SerializationHelper.cs.

Přizpůsobení serializace konkrétní třídy

  1. Set Je vlastní v uzlu pro tuto třídu v části Xml Serializace Chování.

  2. Transformujte všechny šablony, sestavte řešení a prozkoumejte výsledné chyby kompilace. Komentáře v blízkosti každé chyby vysvětlují, jaký kód musíte poskytnout.

Poskytnutí vlastní serializace pro celý model

  1. Přepsání metod v Dsl\GeneratedCode\SerializationHelper.cs

Poznámka:

Počínaje sadou Visual Studio 2022 17.13 už výchozí implementace serializace nepodporuje serializaci nebo deserializaci vlastních datových typů pomocí BinaryFormatter kvůli rizikům zabezpečení s BinaryFormatter.

Pokud používáte vlastní datový typ pro všechny vlastnosti domény, musíte buď přepsat metody serializace ve SerializationHelper třídě, nebo implementovat schopný převést TypeConverter každý vlastní datový typ do a z řetězce.

I když nedoporučujeme používat BinaryFormatter z bezpečnostních důvodů, pokud je nutné zachovat zpětnou kompatibilitu se staršími modely, které používaly BinaryFormatter serializaci, můžete implementovat TypeConverter deserializuje binární data. Následující fragment kódu slouží jako šablona pro implementaci této kompatibility:

class MyCustomDataTypeConverter : TypeConverter
{
    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
    {
        return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType);
    }

    public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
    {
        return destinationType == typeof(string) || base.CanConvertTo(context, destinationType);
    }

    public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
    {
        if (value is string text)
        {
            // First, try to parse the string as if it were returned by MyCustomDataType.ToString().
            if (MyCustomDataType.TryParse(text, out var custom))
                return custom;

            // Fall back to trying to deserialize the old BinaryFormatter serialization format.
            var decoded = Convert.FromBase64String(text);
            using (var memory = new MemoryStream(decoded, false))
            {
                var binaryFormatter = new BinaryFormatter();
                return binaryFormatter.Deserialize(memory) as MyCustomDataType;
            }
        }

        return base.ConvertFrom(context, culture, value);
    }

    public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
    {
        if (destinationType == typeof(string) && value is MyCustomDataType custom)
            return custom.ToString();

        return base.ConvertTo(context, culture, value, destinationType);
    }
}

// ...

[TypeConverter(MyCustomDataTypeConverter)]
class MyCustomDataType
{
    // ...
}

Možnosti v chování serializace XML

V DSL Exploreru uzel Chování serializace xml obsahuje podřízený uzel pro každou třídu domény, relaci, obrazec, spojnici a třídu diagramu. Pod každým z těchto uzlů je seznam vlastností a relací zdrojových v daném prvku. Relace jsou reprezentovány ve svých vlastních právech i ve zdrojových třídách.

Následující tabulka shrnuje možnosti, které můžete nastavit v této části definice DSL. V každém případě vyberte prvek v Průzkumníku DSL a nastavte možnosti v okno Vlastnosti.

Data třídy XML

Tyto prvky jsou nalezeny v DSL Exploreru v části Xml Serialization Behavior\Class Data.

Vlastnost Popis
Má vlastní schéma elementu Pokud je true, znamená to, že třída domény má vlastní schéma elementu.
Je vlastní Nastavte hodnotu True , pokud chcete napsat vlastní serializace a deserializační kód pro tuto třídu domény.

Sestavte řešení a prozkoumejte chyby a zjistěte podrobné pokyny.
Domain – třída Doménová třída, na kterou se vztahuje datový uzel této třídy. Jen pro čtení.
Název prvku Název uzlu XML pro elementy této třídy. Výchozí hodnota je malá a malá verze názvu třídy domény.
Název atributu Moniker Název atributu použitého v elementech monikeru, který obsahuje odkaz. Pokud je hodnota prázdná, použije se název vlastnosti nebo ID klíče.

V tomto příkladu je to "name": <personMoniker name="/Mike Nash"/>
Název elementu Moniker Název elementu XML používaného pro monikers, které odkazují na elementy této třídy.

Výchozí hodnota je malá verze názvu třídy s příponou "Moniker". Například personMoniker.
Název typu monikeru Název typu xsd vygenerovaný pro monikers pro prvky této třídy. XSD je v Dsl\Generated Code\*Schema.xsd
Serializace ID Pokud je true, identifikátor GUID elementu je součástí souboru. Hodnota musí být nastavena na Hodnotu True , pokud neexistuje žádná vlastnost, která je označena je Moniker Key a DSL definuje odkazové relace k této třídě.
Název typu Název typu XML vygenerovaného v xsd z určené třídy domény.
Notes Neformální poznámky přidružené k tomuto prvku

Data vlastností XML

Uzly vlastností XML jsou nalezeny v uzlech třídy.

Vlastnost Popis
Domain – vlastnost Vlastnost, na kterou se vztahují konfigurační data serializace XML. Jen pro čtení.
Je klíč monikeru Pokud je hodnota nastavena na True, vlastnost se používá jako klíč pro vytváření monikers, které odkazují na instance této třídy domény.
Je kvalifikátor Moniker Pokud je hodnota nastavena na True, vlastnost se použije k vytvoření kvalifikátoru v monikers. Pokud false a pokud SerializeId není true pro tuto třídu domény, monikers jsou kvalifikované pomocí moniker nadřazeného elementu ve stromu vkládání.
Reprezentace Pokud je hodnota nastavena na Attribute, vlastnost je serializována jako xml atribut; pokud je hodnota nastavena na Element, pak je serializována jako element; pokud je hodnota nastavena na Ignore, pak není serializována.
Název XML Název použitý pro atribut xml nebo element představující vlastnost. Ve výchozím nastavení je hodnota malá a malá verze názvu vlastnosti domény.
Notes Neformální poznámky přidružené k tomuto prvku

Data role XML

Uzly dat role se nacházejí v uzlech zdrojové třídy.

Vlastnost Popis
Má vlastní moniker Tuto hodnotu nastavte na true, pokud chcete zadat vlastní kód pro generování a překlad monikerů, které procházejí touto relací.

Podrobné pokyny potřebujete, sestavte řešení a poklikejte na chybové zprávy.
Vztah domény Určuje relaci, na kterou se tyto možnosti vztahují. Jen pro čtení.
Vynechat prvek Pokud je hodnota true, uzel XML, který odpovídá zdrojové roli, není ze schématu vynechán.

Pokud mezi zdrojovými a cílovými třídami existuje více relací, tento uzel role rozlišuje mezi propojeními, které patří do těchto dvou relací. Proto doporučujeme tuto možnost v tomto případě nenastavovat.
Název elementu role Určuje název elementu XML odvozeného ze zdrojové role. Výchozí hodnota je název vlastnosti role.
Použít úplný formulář Pokud je hodnota true, každý cílový prvek nebo moniker je uzavřen v uzlu XML představujícím relaci. Pokud má relace vlastní vlastnosti domény, měla by být nastavena na hodnotu true.