Delen via


Schema importeren om klassen te genereren

Gebruik de XsdDataContractImporter klasse om klassen te genereren op basis van schema's die kunnen worden gebruikt met WCF (Windows Communication Foundation). In dit onderwerp worden het proces en de variaties beschreven.

Het importproces

Het importproces van het schema begint met een XmlSchemaSet en produceert een CodeCompileUnit.

Het XmlSchemaSet is een onderdeel van het SCHEMA Object Model (SOM) van .NET Framework dat een set XSD-schemadocumenten (XML Schema Definition Language) vertegenwoordigt. Als u een XmlSchemaSet object wilt maken op basis van een set XSD-documenten, deserialiseert u elk document in een XmlSchema object (met behulp van de XmlSerializer) en voegt u deze objecten toe aan een nieuwe XmlSchemaSet.

Het CodeCompileUnit maakt deel uit van het Code Document Object Model (CodeDOM) van .NET Framework dat .NET Framework-code op een abstracte manier vertegenwoordigt. Als u de werkelijke code van een CodeCompileUnitwilt genereren, gebruikt u een subklasse van de CodeDomProvider klasse, zoals de CSharpCodeProvider of VBCodeProvider klasse.

Een schema importeren

  1. Maak een instantie van de XsdDataContractImporter.

  2. Optioneel. Geef een CodeCompileUnit in de constructor door. De typen die tijdens het importeren van het schema worden gegenereerd, worden toegevoegd aan dit CodeCompileUnit exemplaar in plaats van te beginnen met een lege CodeCompileUnit.

  3. Optioneel. Roep een van de CanImport methoden aan. De methode bepaalt of het opgegeven schema een geldig gegevenscontractschema is en kan worden geïmporteerd. De CanImport methode heeft dezelfde overbelastingen als Import (de volgende stap).

  4. Roep bijvoorbeeld een van de overbelaste Import methoden Import(XmlSchemaSet) aan.

    De eenvoudigste overbelasting neemt een XmlSchemaSet en importeert alle typen, inclusief anonieme typen, die in die schemaset zijn gevonden. Met andere overbelastingen kunt u het XSD-type of een lijst met typen opgeven die moeten worden geïmporteerd (in de vorm van een XmlQualifiedName of een verzameling XmlQualifiedName objecten). In dit geval worden alleen de opgegeven typen geïmporteerd. Een overbelasting neemt een XmlSchemaElement die een bepaald element uit het XmlSchemaSet, evenals het bijbehorende type importeert (ongeacht of het anoniem is of niet). Deze overbelasting retourneert een XmlQualifiedName, die de naam van het gegevenscontract vertegenwoordigt van het type dat voor dit element is gegenereerd.

    Meerdere aanroepen van de Import methode resulteren in meerdere items die aan hetzelfde CodeCompileUnitworden toegevoegd. Er wordt geen type gegenereerd in het CodeCompileUnit type als dit al bestaat. Roep Import meerdere keren op hetzelfde XsdDataContractImporter aan in plaats van meerdere XsdDataContractImporter objecten te gebruiken. Dit is de aanbevolen manier om te voorkomen dat er dubbele typen worden gegenereerd.

    Notitie

    Als er een fout optreedt tijdens het importeren, heeft deze CodeCompileUnit een onvoorspelbare status. Als u een CodeCompileUnit gevolg van een mislukte importbewerking gebruikt, kunt u worden blootgesteld aan beveiligingsproblemen.

  5. Toegang tot de CodeCompileUnit eigenschap via de CodeCompileUnit eigenschap.

Importopties: de gegenereerde typen aanpassen

U kunt de Options eigenschap van de XsdDataContractImporter klasse instellen op een exemplaar van de ImportOptions klasse om verschillende aspecten van het importproces te beheren. Een aantal opties is rechtstreeks van invloed op de typen die worden gegenereerd.

Het toegangsniveau beheren (GenerateInternal of de interne switch)

Dit komt overeen met de /interne schakeloptie van het Hulpprogramma voor metagegevens van ServiceModel (Svcutil.exe).>

Normaal gesproken worden openbare typen gegenereerd op basis van het schema, met privévelden en overeenkomende eigenschappen van openbare gegevenslid. Als u in plaats daarvan interne typen wilt genereren, stelt u de GenerateInternal eigenschap in op true.

In het volgende voorbeeld ziet u een schema dat is getransformeerd in een interne klasse wanneer de GenerateInternal eigenschap is ingesteld op true.

[DataContract]
internal partial class Vehicle : IExtensibleDataObject
{
    private int yearField;
    private string colorField;

    [DataMember]
    internal int year
    {
        get { return this.yearField; }
        set { this.yearField = value; }
    }
    [DataMember]
    internal string color
    {
        get { return this.colorField; }
        set { this.colorField = value; }
    }

    private ExtensionDataObject extensionDataField;
    public ExtensionDataObject ExtensionData
    {
        get { return this.extensionDataField; }
        set { this.extensionDataField = value; }
    }
}
Class Vehicle
    Implements IExtensibleDataObject
    Private yearField As Integer
    Private colorField As String

    <DataMember()> _
    Friend Property year() As Integer
        Get
            Return Me.yearField
        End Get
        Set
            Me.yearField = value
        End Set
    End Property

    <DataMember()> _
    Friend Property color() As String
        Get
            Return Me.colorField
        End Get
        Set
            Me.colorField = value
        End Set
    End Property
    Private extensionDataField As ExtensionDataObject

    Public Property ExtensionData() As ExtensionDataObject _
        Implements IExtensibleDataObject.ExtensionData
        Get
            Return Me.extensionDataField
        End Get
        Set(ByVal value As ExtensionDataObject)
            Me.extensionDataField = value
        End Set
    End Property
End Class

Naamruimten beheren (naamruimten of de schakeloptie /naamruimte)

Dit komt overeen met de /namespace-switch in het Svcutil.exe hulpprogramma.

Normaal gesproken worden typen gegenereerd op basis van schema's in .NET Framework-naamruimten, waarbij elke XSD-naamruimte overeenkomt met een bepaalde .NET Framework-naamruimte volgens een toewijzing die wordt beschreven in datacontractschemareferenties. U kunt deze toewijzing door de Namespaces eigenschap aanpassen aan een Dictionary<TKey,TValue>. Als een bepaalde XSD-naamruimte wordt gevonden in de woordenlijst, wordt de overeenkomende .NET Framework-naamruimte ook uit uw woordenlijst gehaald.

Denk bijvoorbeeld aan het volgende schema.

<xs:schema targetNamespace="http://schemas.contoso.com/carSchema">
  <xs:complexType name="Vehicle">
    <!-- details omitted... -->
  </xs:complexType>
</xs:schema>

In het volgende voorbeeld wordt de Namespaces eigenschap gebruikt om de http://schemas.contoso.com/carSchema naamruimte toe te wijzen aan Contoso.Cars.

XsdDataContractImporter importer = new XsdDataContractImporter();
importer.Options.Namespaces.Add(new KeyValuePair<string, string>("http://schemas.contoso.com/carSchema", "Contoso.Cars"));
Dim importer As New XsdDataContractImporter
importer.Options.Namespaces.Add(New KeyValuePair(Of String, String)("http://schemas.contoso.com/carSchema", "Contoso.Cars"))

De SerializableAttribute toevoegen (GenerateSerializable of de /serializable switch)

Dit komt overeen met de /serialiseerbare schakelaar van het Svcutil.exe hulpprogramma.

Soms is het belangrijk dat de typen die zijn gegenereerd op basis van het schema, kunnen worden gebruikt met .NET Framework Runtime-serialisatie-engines. Dit is handig bij het gebruik van typen voor externe communicatie van .NET Framework. Als u dit wilt inschakelen, moet u het SerializableAttribute kenmerk toepassen op de gegenereerde typen naast het normale DataContractAttribute kenmerk. Het kenmerk wordt automatisch gegenereerd als de GenerateSerializable importoptie is ingesteld op true.

In het volgende voorbeeld ziet u de Vehicle klasse die is gegenereerd met de GenerateSerializable importoptie ingesteld op true.

[DataContract]
[Serializable]
public partial class Vehicle : IExtensibleDataObject
{
    // Code not shown.
    public ExtensionDataObject ExtensionData
    {
        get
        {
            throw new Exception("The method or operation is not implemented.");
        }
        set
        {
            throw new Exception("The method or operation is not implemented.");
        }
    }
}
<DataContract(), Serializable()> _
Partial Class Vehicle
    Implements IExtensibleDataObject
    Private extensionDataField As ExtensionDataObject

    ' Code not shown.

    Public Property ExtensionData() As ExtensionDataObject _
        Implements IExtensibleDataObject.ExtensionData
        Get
            Return Me.extensionDataField
        End Get
        Set(ByVal value As ExtensionDataObject)
            Me.extensionDataField = value
        End Set
    End Property

End Class

Ondersteuning voor gegevensbinding toevoegen (EnableDataBinding of de schakeloptie /enableDataBinding)

Dit komt overeen met de schakeloptie /enableDataBinding op het hulpprogramma Svcutil.exe.

Soms wilt u de typen die zijn gegenereerd op basis van het schema binden aan grafische onderdelen van de gebruikersinterface, zodat elke update naar exemplaren van deze typen de gebruikersinterface automatisch bijwerkt. De XsdDataContractImporter functie kan typen genereren die de INotifyPropertyChanged interface zodanig implementeren dat elke eigenschapswijziging een gebeurtenis activeert. Als u typen genereert voor gebruik met een client-UI-programmeeromgeving die deze interface ondersteunt (zoals Windows Presentation Foundation (WPF)), stelt u de EnableDataBinding eigenschap in om deze functie in te true schakelen.

In het volgende voorbeeld ziet u de Vehicle klasse die is gegenereerd met de EnableDataBinding set op true.

[DataContract]
public partial class Vehicle : IExtensibleDataObject, INotifyPropertyChanged
{
    private int yearField;
    private string colorField;

    [DataMember]
    public int year
    {
        get { return this.yearField; }
        set
        {
            if (this.yearField.Equals(value) != true)
            {
                this.yearField = value;
                this.RaisePropertyChanged("year");
            }
        }
    }
    [DataMember]
    public string color
    {
        get { return this.colorField; }
        set
        {
            if (this.colorField.Equals(value) != true)
            {
                this.colorField = value;
                this.RaisePropertyChanged("color");
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected void RaisePropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler propertyChanged =
this.PropertyChanged;
        if (propertyChanged != null)
        {
            propertyChanged(this,
new PropertyChangedEventArgs(propertyName));
        }
    }

    private ExtensionDataObject extensionDataField;
    public ExtensionDataObject ExtensionData
    {
        get { return this.extensionDataField; }
        set { this.extensionDataField = value; }
    }
}
Partial Class Vehicle
    Implements IExtensibleDataObject, INotifyPropertyChanged
    Private yearField As Integer
    Private colorField As String

    <DataMember()> _
    Public Property year() As Integer
        Get
            Return Me.yearField
        End Get
        Set
            If Me.yearField.Equals(value) <> True Then
                Me.yearField = value
                Me.RaisePropertyChanged("year")
            End If
        End Set
    End Property

    <DataMember()> _
    Public Property color() As String
        Get
            Return Me.colorField
        End Get
        Set
            If Me.colorField.Equals(value) <> True Then
                Me.colorField = value
                Me.RaisePropertyChanged("color")
            End If
        End Set
    End Property

    Public Event PropertyChanged As PropertyChangedEventHandler _
      Implements INotifyPropertyChanged.PropertyChanged

    Private Sub RaisePropertyChanged(ByVal propertyName As String)
        RaiseEvent PropertyChanged(Me, _
         New PropertyChangedEventArgs(propertyName))
    End Sub

    Private extensionDataField As ExtensionDataObject

    Public Property ExtensionData() As ExtensionDataObject _
        Implements IExtensibleDataObject.ExtensionData
        Get
            Return Me.extensionDataField
        End Get
        Set(ByVal value As ExtensionDataObject)
            Me.extensionDataField = value
        End Set
    End Property

End Class

Importopties: Verzamelingstypen kiezen

Twee speciale patronen in XML vertegenwoordigen verzamelingen items: lijsten met items en koppelingen tussen het ene item en het andere. Hier volgt een voorbeeld van een lijst met tekenreeksen.

<People>
  <person>Alice</person>
  <person>Bob</person>
  <person>Charlie</person>
</People>

Hier volgt een voorbeeld van een koppeling tussen een tekenreeks en een geheel getal (city name en population).

<Cities>
  <city>
    <name>Auburn</name>
    <population>40000</population>
  </city>
  <city>
    <name>Bellevue</name>
    <population>80000</population>
  </city>
  <city>
    <name>Cedar Creek</name>
    <population>10000</population>
  </city>
</Cities>

Notitie

Elke koppeling kan ook worden beschouwd als een lijst. U kunt de voorgaande koppeling bijvoorbeeld weergeven als een lijst met complexe city objecten die twee velden bevatten (een tekenreeksveld en een geheel getalveld). Beide patronen hebben een weergave in het XSD-schema. Er is geen manier om onderscheid te maken tussen een lijst en een koppeling, dus dergelijke patronen worden altijd behandeld als lijsten, tenzij een speciale aantekening die specifiek is voor WCF aanwezig is in het schema. De aantekening geeft aan dat een bepaald patroon een koppeling vertegenwoordigt. Zie Data Contract Schema Reference voor meer informatie.

Normaal gesproken wordt een lijst geïmporteerd als een verzamelingsgegevenscontract dat is afgeleid van een algemene lijst of als .NET Framework-matrix, afhankelijk van of het schema het standaardnaamgevingspatroon voor verzamelingen volgt. Dit wordt in meer detail beschreven in verzamelingstypen in gegevenscontracten. Koppelingen worden normaal gesproken geïmporteerd als een Dictionary<TKey,TValue> of een verzamelingsgegevenscontract dat is afgeleid van het woordenlijstobject. Denk bijvoorbeeld aan het volgende schema.

<xs:complexType name="Vehicle">
  <xs:sequence>
    <xs:element name="year" type="xs:int"/>
    <xs:element name="color" type="xs:string"/>
    <xs:element name="passengers" type="people"/>
  </xs:sequence>
</xs:complexType>
<xs:complexType name="people">
  <xs:sequence>
    <xs:element name="person" type="xs:string" maxOccurs="unbounded" />
  </xs:sequence>
</xs:complexType>

Dit wordt als volgt geïmporteerd (velden worden weergegeven in plaats van eigenschappen voor leesbaarheid).

[DataContract]
public partial class Vehicle : IExtensibleDataObject
{
    [DataMember] public int yearField;
    [DataMember] public string colorField;
    [DataMember] public people passengers;

    // Other code not shown.

    public ExtensionDataObject ExtensionData
    {
        get
        {
            throw new Exception("The method or operation is not implemented.");
        }
        set
        {
            throw new Exception("The method or operation is not implemented.");
        }
    }
}
[CollectionDataContract(ItemName = "person")]
public class people : List<string> { }
Public Partial Class Vehicle
    Implements IExtensibleDataObject

    <DataMember()> _
    Public yearField As Integer
    <DataMember()> _
    Public colorField As String
    <DataMember()> _
    Public passengers As people

    ' Other code not shown.

    Public Property ExtensionData() As ExtensionDataObject _
    Implements IExtensibleDataObject.ExtensionData
        Get
            Throw New Exception("The method or operation is not implemented.")
        End Get
        Set
            Throw New Exception("The method or operation is not implemented.")
        End Set
    End Property
End Class

<CollectionDataContract(ItemName:="person")> _
Public Class people
    Inherits List(Of String)
End Class

Het is mogelijk om de verzamelingstypen aan te passen die worden gegenereerd voor dergelijke schemapatronen. U kunt bijvoorbeeld verzamelingen genereren die zijn afgeleid van de BindingList<T> in plaats van de List<T> klasse om het type aan een keuzelijst te binden en deze automatisch te laten bijwerken wanneer de inhoud van de verzameling wordt gewijzigd. Hiervoor stelt u de ReferencedCollectionTypes eigenschap van de ImportOptions klasse in op een lijst met verzamelingstypen die moeten worden gebruikt (hierna bekend als de typen waarnaar wordt verwezen). Bij het importeren van een verzameling wordt deze lijst met typen verzamelingen waarnaar wordt verwezen gescand en wordt de best overeenkomende verzameling gebruikt als deze wordt gevonden. Koppelingen worden alleen vergeleken met typen die de algemene of niet-generische IDictionary interface implementeren, terwijl lijsten worden vergeleken met elk ondersteund verzamelingstype.

Als de ReferencedCollectionTypes eigenschap bijvoorbeeld is ingesteld op een BindingList<T>, wordt het people type in het voorgaande voorbeeld als volgt gegenereerd.

[CollectionDataContract(ItemName = "person")]
public class people : BindingList<string> { }
<CollectionDataContract(ItemName:="person")> _
Public Class people
    Inherits BindingList(Of String)

Een gesloten algemeen wordt beschouwd als de beste overeenkomst. Als de typen BindingList(Of Integer) bijvoorbeeld worden doorgegeven aan ArrayList de verzameling van typen waarnaar wordt verwezen, worden alle lijsten met gehele getallen in het schema geïmporteerd als een BindingList(Of Integer). Alle andere lijsten, bijvoorbeeld een List(Of String), worden geïmporteerd als een ArrayList.

Als een type waarmee de algemene IDictionary interface wordt geïmplementeerd, wordt toegevoegd aan de verzameling van typen waarnaar wordt verwezen, moeten de typeparameters volledig open of volledig gesloten zijn.

Duplicaten zijn niet toegestaan. U kunt bijvoorbeeld niet zowel een als List(Of Integer) een Collection(Of Integer) toevoegen aan de typen waarnaar wordt verwezen. Dit maakt het onmogelijk om te bepalen welke waarden moeten worden gebruikt wanneer een lijst met gehele getallen in het schema wordt gevonden. Duplicaten worden alleen gedetecteerd als er een type in het schema is dat het probleem met duplicaten weergeeft. Als het geïmporteerde schema bijvoorbeeld geen lijsten met gehele getallen bevat, mag het zowel de verzameling als List(Of Integer) de Collection(Of Integer) verzameling met verwijzingen hebben, maar geen van beide gevolgen hebben.

Het mechanisme voor verzamelingstypen waarnaar wordt verwezen, werkt even goed voor verzamelingen van complexe typen (inclusief verzamelingen van andere verzamelingen) en niet alleen voor verzamelingen primitieven.

De ReferencedCollectionTypes eigenschap komt overeen met de schakeloptie /collectionType in het hulpprogramma SvcUtil.exe. Als u wilt verwijzen naar meerdere verzamelingstypen, moet de schakeloptie /collectionType meerdere keren worden opgegeven. Als het type zich niet in de MsCorLib.dll bevindt, moet er ook naar de assembly worden verwezen met behulp van de /reference-switch .

Importopties: Verwijzen naar bestaande typen

Af en toe komen typen in het schema overeen met bestaande .NET Framework-typen en hoeven deze typen niet helemaal opnieuw te worden gegenereerd. (Deze sectie is alleen van toepassing op niet-collectietypen. Zie de voorgaande sectie voor verzamelingstypen.)

U hebt bijvoorbeeld een standaardgegevenscontracttype 'Persoon' dat u altijd wilt gebruiken bij het vertegenwoordigen van een persoon. Wanneer een bepaalde service gebruikmaakt van dit type en het bijbehorende schema wordt weergegeven in de metagegevens van de service, kunt u het bestaande Person type opnieuw gebruiken bij het importeren van dit schema in plaats van een nieuw type te genereren voor elke service.

Hiervoor geeft u een lijst met .NET Framework-typen door die u opnieuw wilt gebruiken in de verzameling die door de ReferencedTypes eigenschap wordt geretourneerd voor de ImportOptions klasse. Als een van deze typen een naam en naamruimte voor een gegevenscontract heeft die overeenkomt met de naam en naamruimte van een schematype, wordt een structurele vergelijking uitgevoerd. Als wordt vastgesteld dat de typen zowel overeenkomende namen als overeenkomende structuren hebben, wordt het bestaande .NET Framework-type opnieuw gebruikt in plaats van een nieuwe te genereren. Als alleen de naam overeenkomt met maar niet de structuur, wordt er een uitzondering gegenereerd. Houd er rekening mee dat er geen vergoeding is voor versiebeheer bij het verwijzen naar typen (bijvoorbeeld het toevoegen van nieuwe optionele gegevensleden). De structuren moeten exact overeenkomen.

Het is wettelijk om meerdere typen met dezelfde naam en naamruimte toe te voegen aan de verzameling waarnaar wordt verwezen, zolang er geen schematypen met die naam en naamruimte worden geïmporteerd. Hierdoor kunt u eenvoudig alle typen in een assembly toevoegen aan de verzameling zonder dat u zich zorgen hoeft te maken over duplicaten voor typen die niet in het schema voorkomen.

De ReferencedTypes eigenschap komt overeen met de /reference-switch in bepaalde bewerkingsmodi van het hulpprogramma Svcutil.exe.

Notitie

Wanneer u de Svcutil.exe of (in Visual Studio) gebruikt, worden alle typen in MsCorLib.dll automatisch verwezen.

Importopties: Niet-DataContract-schema importeren als IXmlSerializable-typen

Het XsdDataContractImporter ondersteunt een beperkte subset van het schema. Als er niet-ondersteunde schemaconstructies aanwezig zijn (bijvoorbeeld XML-kenmerken), mislukt de importpoging met een uitzondering. Het instellen van de ImportXmlType eigenschap om het bereik van het ondersteunde schema uit te true breiden. Wanneer dit is ingesteld true, worden de XsdDataContractImporter typen gegenereerd die de IXmlSerializable interface implementeren. Hiermee hebt u directe toegang tot de XML-weergave van deze typen.

Overwegingen bij het ontwerpen
  • Het kan lastig zijn om rechtstreeks te werken met de zwak getypte XML-weergave. Overweeg het gebruik van een alternatieve serialisatie-engine, zoals de XmlSerializer, om te werken met schema's die niet compatibel zijn met gegevenscontracten op een sterk getypte manier. Zie De XmlSerializer-klasse gebruiken voor meer informatie.

  • Sommige schemaconstructies kunnen niet worden geïmporteerd door de XsdDataContractImporter even wanneer de ImportXmlType eigenschap is ingesteld op true. Overweeg nogmaals het gebruik van de XmlSerializer voor dergelijke gevallen.

  • De exacte schemaconstructies die worden ondersteund, zowel wanneer ImportXmlType als falsetrue worden beschreven in datacontractschemareferenties.

  • Het schema voor gegenereerde IXmlSerializable typen behoudt geen betrouwbaarheid bij het importeren en exporteren. Dat wil gezegd: het exporteren van het schema van de gegenereerde typen en importeren als klassen retourneert het oorspronkelijke schema niet.

Het is mogelijk om de ImportXmlType optie te combineren met de ReferencedTypes eerder beschreven optie. Voor typen die moeten worden gegenereerd als IXmlSerializable implementaties, wordt de structurele controle overgeslagen bij het gebruik van de ReferencedTypes functie.

De ImportXmlType optie komt overeen met de schakeloptie /importXmlTypes op het hulpprogramma Svcutil.exe.

Werken met gegenereerde IXmlSerializable Types

De gegenereerde IXmlSerializable typen bevatten een privéveld met de naam 'nodesField', dat een matrix met XmlNode objecten retourneert. Wanneer u een exemplaar van een dergelijk type deserialiseert, hebt u rechtstreeks via dit veld toegang tot de XML-gegevens met behulp van het XML-documentobjectmodel. Wanneer u een exemplaar van dit type serialiseert, kunt u dit veld instellen op de gewenste XML-gegevens en deze worden geserialiseerd.

Dit wordt bereikt via de IXmlSerializable implementatie. In het gegenereerde IXmlSerializable type roept de ReadXml implementatie de ReadNodes methode van de XmlSerializableServices klasse aan. De methode is een helpermethode waarmee XML wordt geconverteerd XmlReader naar een matrix met XmlNode objecten. De WriteXml implementatie doet het tegenovergestelde en converteert de matrix van XmlNode objecten naar een reeks XmlWriter aanroepen. Dit wordt bereikt met behulp van de WriteNodes methode.

Het is mogelijk om het schema-exportproces uit te voeren op de gegenereerde IXmlSerializable klassen. Zoals eerder vermeld, krijgt u het oorspronkelijke schema niet terug. In plaats daarvan krijgt u het standaard XSD-type anyType, een jokerteken voor elk XSD-type.

Dit wordt bereikt door het XmlSchemaProviderAttribute kenmerk toe te passen op de gegenereerde IXmlSerializable klassen en een methode op te geven waarmee de AddDefaultSchema methode wordt aangeroepen om het type anyType te genereren.

Notitie

Het XmlSerializableServices type bestaat alleen ter ondersteuning van deze specifieke functie. Het wordt niet aanbevolen voor gebruik voor andere doeleinden.

Importopties: Geavanceerde opties

Hier volgen geavanceerde importopties:

Zie ook