Freigeben über


Bindungsunterstützung für das choice-Element

.NET Framework stellt Bindungsunterstützung für das <choice>-Element bereit.

Wenn sich einzelne Typen der choice-Elemente, einschließlich ihrer Namen, voneinander unterscheiden, wendet Xsd.exe nur XmlElementAttribute-Attribute auf einen öffentlichen Member an. Wenn sie sich nur ihrem Namen nach unterscheiden, wendet Xsd.exe zusätzlich ein XmlChoiceIdentifierAttribute an und fügt zur Differenzierung zusätzliche Logik hinzu.

Erklärung

Das <choice>-Element enthält mindestens zwei untergeordnete Elemente, von denen jedes ein Element oder eine Gruppe von Elementen darstellt. Es gibt an, dass nur eine dieser Entitäten in einem bestimmten Instanzendokument an der festgelegten Position angezeigt werden kann. Die Auswahlmöglichkeiten müssen sich nach Elementnamen unterscheiden. Sie können sich auch nach Elementtyp unterscheiden und, falls die Auswahlmöglichkeit eine Gruppierung ist (etwa ein <group>-Element), auch hinsichtlich der Anzahl der Elemente.

Mehrdeutige Kombinationen von Gruppen erzeugen unvorhersehbare Ergebnisse.

Unterscheidung nach Typ

Der einfachste Fall liegt vor, wenn sich die Typen der einzelnen Elemente voneinander unterscheiden, einschließlich ihrer Namen. Betrachten Sie folgende <choice>-Definition:

<xsd:choice>
    <xsd:element name="numberA" type="xsd:int"/>
    <xsd:element name="numberB" type="xsd:decimal"/>
</xsd:choice>

In C# würde Xsd.exe diesen XML-Schemainhalt in den folgenden Code übersetzen:

[System.Xml.Serialization.XmlElementAttribute("numberA", typeof(int))]
[System.Xml.Serialization.XmlElementAttribute("numberB", typeof(System.Decimal))]
public object Item;

Im generierten Code wird dem Feld der object-Typ zugewiesen, aber es führt auch zwei XmlElementAttribute-Attribute mit sich. Ein Attribut gibt an, dass der Typ als eine int-Instanz zu serialisieren ist; das andere gibt an, dass der Typ als eine System.Decimal-Instanz zu serialisieren ist. In diesem Fall verwendet die XmlSerializer-Klasse den dem Objekt zur Zeit zugewiesenen Typ. Mit der folgenden Zuweisung zu einem int-Objekt wird das <numberA>-Element verwendet:

Item = 1;

Immer dann, wenn die Auswahlmöglichkeiten unterschiedliche XML-Schemadatentypen aufweisen, bindet Xsd.exe jeden Datentyp an eine unterschiedliche Klasse. Da System.Object der Stammtyp der .NET Framework-Typenhierarchie ist, gehört das generierte Feld stets zu einem gängigen Basistyp. Die Object-Klasse ist der generischste allgemeine Basistyp.

Wenn die Auswahlmöglichkeiten alle von einem gängigen durch XML-Schema definierten Datentyp abgeleitet sind, etwa durch das <extension>-Konstrukt, dann ist der Feldtyp eine Bindung dieses Datentyps. Angenommen, ein <choice>-Element bietet eine Auswahlmöglichkeit zwischen Element <a> vom Typ DerivedTypeA und Element <b> vom Typ DerivedTypeB und diese beide Typen erweitern den Typ BaseType. In C# wird dann folgender Quellcode erzeugt:

[System.Xml.Serialization.XmlElementAttribute("a", typeof(DerivedTypeA))]
[System.Xml.Serialization.XmlElementAttribute("b", typeof(DerivedTypeB))]
public BaseType Item;

Unterscheidung nach Name

Wenn sich die Auswahltypen nicht unterscheiden, erfolgt die Auswahl des Elementnamens bei Erstellung des Instanzendokuments durch Verwendung des XmlChoiceIdentifierAttribute-Attributs. Betrachten Sie die folgende <choice>-Definition:

<xsd:choice>
    <xsd:element name="stringA" type="xsd:string"/>
    <xsd:element name="stringB" type="xsd:string"/>
</xsd:choice>

Xsd.exe würde diesen XML-Schemainhalt in folgenden Code übersetzen:

[System.Xml.Serialization.XmlElementAttribute("stringA", typeof(string))]
[System.Xml.Serialization.XmlElementAttribute("stringB", typeof(string))]
[System.Xml.Serialization.XmlChoiceIdentifierAttribute("ItemElementName")]
public string Item;

[System.Xml.Serialization.XmlIgnoreAttribute()]
public ItemChoiceType ItemElementName;
...
public enum ItemChoiceType {
        
    stringA,
        
    stringB,
}

Das Item-Feld verfügt über ein XmlChoiceIdentifier-Attribut, zusätzlich zu den beiden XmlElement-Attributen. Der Parameter zum XmlChoiceIdentifier-Attribut ist der Name einer Enumerationsinstanz. Der entsprechende Enumerationstyp enthält die Elementauswahlwerte. Die Enumerationsinstanz wird mit einem XmlIgnore-Attribut angezeigt, damit ihr Wert nicht serialisiert werden kann.

Der Entwickler muss dann Code schreiben, um der Enumerationsinstanz einen Wert zuzuweisen. Die folgende Zeile erledigt das für ein Objekt mit dem Namen i:

i.ItemElementName = ItemChoiceType.stringA;

Weitere Informationen finden Sie in den Ausführungen zur XmlChoiceIdentifierAttribute-Klasse.

Beispiel

Das folgende Eingabe-XML-Schemadokument veranschaulicht verschiedene Verwendungen der <choice>-Gruppierung:

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
            targetNamespace="http://example.org/" xmlns="http://example.org/" elementFormDefault="qualified">
    <xsd:element name="choicesInstance" type="MyChoicesType"/>

    <xsd:complexType name="MyComplexType">
        <xsd:sequence>
            <xsd:element name="field1" type="xsd:string"/>
            <xsd:element name="field2" type="xsd:string"/>
        </xsd:sequence>
    </xsd:complexType>

    <xsd:complexType name="DerivedTypeA">
        <xsd:complexContent>
            <xsd:extension base="MyComplexType">
                 <xsd:attribute name="extraInfoForA" type="xsd:string"/>
            </xsd:extension>
        </xsd:complexContent>
    </xsd:complexType>

    <xsd:complexType name="DerivedTypeB">
        <xsd:complexContent>
            <xsd:extension base="MyComplexType">
                 <xsd:attribute name="extraInfoForB" type="xsd:string"/>
            </xsd:extension>
        </xsd:complexContent>
    </xsd:complexType>

    <xsd:complexType name="MyChoicesType">
        <xsd:sequence>
            <xsd:element name="name" type="xsd:string"/>
            <xsd:choice>
                <xsd:element name="stringA" type="xsd:string"/>
                <xsd:element name="stringB" type="xsd:string"/>
            </xsd:choice>
            <xsd:choice>
                <xsd:element name="numberA" type="xsd:int"/>
                <xsd:element name="numberB" type="xsd:decimal"/>
            </xsd:choice>
            <xsd:choice>
                <xsd:element name="complexA" type="MyComplexType"/>
                <xsd:element name="complexB" type="MyComplexType"/>
                <xsd:element name="simpleC"  type="xsd:string"/>
            </xsd:choice>
            <xsd:choice>
                <xsd:element name="derivedA" type="DerivedTypeA"/>
                <xsd:element name="derivedB" type="DerivedTypeB"/>
            </xsd:choice>
        </xsd:sequence>
    </xsd:complexType>
</xsd:schema>

Aus dem vorhergehenden XML-Schemadokument generierte C#-Klassen:

[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://example.org/")]
[System.Xml.Serialization.XmlRootAttribute("choicesInstance", Namespace="http://example.org/", IsNullable=false)]
 public class MyChoicesType {
        
     public string name;
        
    [System.Xml.Serialization.XmlElementAttribute("stringA", typeof(string))]
    [System.Xml.Serialization.XmlElementAttribute("stringB", typeof(string))]
    [System.Xml.Serialization.XmlChoiceIdentifierAttribute("ItemElementName")]
    public string Item;
        
    [System.Xml.Serialization.XmlIgnoreAttribute()]
    public ItemChoiceType ItemElementName;
        
    [System.Xml.Serialization.XmlElementAttribute("numberA", typeof(int))]
    [System.Xml.Serialization.XmlElementAttribute("numberB", typeof(System.Decimal))]
    public object Item1;
        
    [System.Xml.Serialization.XmlElementAttribute("complexA", typeof(MyComplexType))]
    [System.Xml.Serialization.XmlElementAttribute("complexB", typeof(MyComplexType))]
    [System.Xml.Serialization.XmlElementAttribute("simpleC", typeof(string))]
    [System.Xml.Serialization.XmlChoiceIdentifierAttribute("Item2ElementName")]
    public object Item2;
        
    [System.Xml.Serialization.XmlIgnoreAttribute()]
    public Item2ChoiceType Item2ElementName;
        
    [System.Xml.Serialization.XmlElementAttribute("derivedA", typeof(DerivedTypeA))]
    [System.Xml.Serialization.XmlElementAttribute("derivedB", typeof(DerivedTypeB))]
    public MyComplexType Item3;
}
    
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://example.org/", IncludeInSchema=false)]
public enum ItemChoiceType {
        
    stringA,
        
    stringB,
}
    
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://example.org/")]
[System.Xml.Serialization.XmlIncludeAttribute(typeof(DerivedTypeB))]
[System.Xml.Serialization.XmlIncludeAttribute(typeof(DerivedTypeA))]
public class MyComplexType {
        
    public string field1;
        
    public string field2;
}
    
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://example.org/")]
    public class DerivedTypeA : MyComplexType {
        
        [System.Xml.Serialization.XmlAttributeAttribute()]
        public string extraInfoForA;
    }
    
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://example.org/")]
public class DerivedTypeB : MyComplexType {
        
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string extraInfoForB;
}
    
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://example.org/", IncludeInSchema=false)]
public enum Item2ChoiceType {
        
    complexA,
        
    complexB,
        
    simpleC,
}

Ein primäres XML-Schemadokument, das aus einer Assembly generiert wurde, die ihrerseits aus dem vorhergehenden C#-Quellcode kompiliert wurde. (Eine zweite XSD-Datei, die zum Definieren willkürlicher globaler Elemente für komplexe Typen generiert wird, ist hier nicht aufgeführt.)

<xs:schema xmlns:tns="http://example.org/" elementFormDefault="qualified" targetNamespace="http://example.org/" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="choicesInstance" type="tns:MyChoicesType" />
  <xs:complexType name="MyChoicesType">
    <xs:sequence>
      <xs:element minOccurs="0" maxOccurs="1" name="name" type="xs:string" />
      <xs:choice minOccurs="1" maxOccurs="1">
        <xs:element minOccurs="0" maxOccurs="1" name="stringA" type="xs:string" />
        <xs:element minOccurs="0" maxOccurs="1" name="stringB" type="xs:string" />
      </xs:choice>
      <xs:choice minOccurs="1" maxOccurs="1">
        <xs:element minOccurs="1" maxOccurs="1" name="numberA" type="xs:int" />
        <xs:element minOccurs="1" maxOccurs="1" name="numberB" type="xs:decimal" />
      </xs:choice>
      <xs:choice minOccurs="1" maxOccurs="1">
        <xs:element minOccurs="0" maxOccurs="1" name="complexA" type="tns:MyComplexType" />
        <xs:element minOccurs="0" maxOccurs="1" name="simpleC" type="xs:string" />
        <xs:element minOccurs="0" maxOccurs="1" name="complexB" type="tns:MyComplexType" />
      </xs:choice>
      <xs:choice minOccurs="1" maxOccurs="1">
        <xs:element minOccurs="0" maxOccurs="1" name="derivedB" type="tns:DerivedTypeB" />
        <xs:element minOccurs="0" maxOccurs="1" name="derivedA" type="tns:DerivedTypeA" />
      </xs:choice>
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="MyComplexType">
    <xs:sequence>
      <xs:element minOccurs="0" maxOccurs="1" name="field1" type="xs:string" />
      <xs:element minOccurs="0" maxOccurs="1" name="field2" type="xs:string" />
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="DerivedTypeA">
    <xs:complexContent mixed="false">
      <xs:extension base="tns:MyComplexType">
        <xs:attribute name="extraInfoForA" type="xs:string" />
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>
  <xs:complexType name="DerivedTypeB">
    <xs:complexContent mixed="false">
      <xs:extension base="tns:MyComplexType">
        <xs:attribute name="extraInfoForB" type="xs:string" />
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>
</xs:schema>
Mögliche Attribute Bindungsunterstützung

id

Das Dienstprogramm Xsd.exe ignoriert das id-Attribut, mit dem ein eindeutiger Bezeichner bereitgestellt werden soll.

maxOccurs

Für das <choice>-Element wird ein maxOccurs-Wert von 0 von Xsd.exe als 1 interpretiert. Ein maxOccurs-Wert größer 1 wird als unbounded interpretiert.

Für einen Wert von 1 erzeugt Xsd.exe Code, wie unter Differentiating by Type und Differentiating by Name erklärt.

Beim Wert unbounded führt Xsd.exe die gleiche Bindung aus, mit der Ausnahme, dass das generierte Feld für die Auswahl ein Array eines entsprechenden Typs ist. Wenn alle Auswahlmöglichkeiten vom gleichen Typ sind, ist das zweite Feld (identifiziert durch das XmlChoiceIdentifier-Attribut) ein Array des generierten Enumerationstyps. Jedes Element im zweiten Array legt den Elementnamen für das entsprechende Element im ersten Array fest.

Weitere Informationen finden Sie in den Ausführungen zum Bindungsunterstützung für das maxOccurs-Attribut-Attribut.

minOccurs

Beim Generieren von Quellcode aus einem XML-Schemadokument ignoriert Xsd.exe das minOccurs-Attribut, das auf das <choice>-Element angewendet wird.

Beim Generieren eines XML-Schemadokuments aus Klassen erzeugt Xsd.exe ein <choice>-Element mit einem minOccurs-Wert von 1, wenn die Auswahlmöglichkeit ein einzelnes Objekt darstellt, oder 0, wenn die Auswahlmöglichkeit ein Array darstellt.

Weitere Informationen finden Sie in den Ausführungen zum Bindungsunterstützung für das minOccurs-Attribut-Attribut.

Mögliche übergeordnete Elemente: <choice>, <complexType>, <extension>, <group>, <restriction>, <sequence>

Mögliche untergeordnete Elemente: <annotation>, <any>, <element>, <group>, <sequence>, <choice>

Siehe auch

Referenz

XmlSchemaChoice

Footer image

Copyright © 2007 by Microsoft Corporation. Alle Rechte vorbehalten.