Freigeben über


Bindungsunterstützung für das maxOccurs-Attribut

Dieses Thema bezieht sich auf eine veraltete Technologie. XML-Webdienste und XML-Webdienstclients sollten nun mithilfe der folgenden Technologie erstellt werden: Windows Communication Foundation.

.NET Framework stellt partielle Bindungsunterstützung für das maxOccurs-Attribut bereit.

Bei den meisten Elementen, die ein maxOccurs-Attribut angeben können, interpretiert Xsd.exe den Wert 0 als 1 und erstellt ein Nicht-Arrayfeld. Ein Wert größer als 1 wird als unbounded interpretiert und dadurch ein Arrayfeld erstellt. Die einzelnen Elemente zeigen ein unterschiedliches Verhalten.

Erklärung

Mit dem maxOccurs-Attribut und dem minOccurs-Attribut wird einschränkend festgelegt, wie oft in Folge die angegebene Entität in der entsprechenden Position in einem XML-Instanzendokument angezeigt werden kann.

Diese Attribute werden nur in komplexen Typdefinitionen angezeigt. Damit das <element>-Element oder das <group>-Element über diese Attribute verfügt, muss es sich beim entsprechenden Element um eine lokale Deklaration oder einen Verweis auf eine globale Deklaration und nicht um die eigentliche globale Deklaration handeln.

Zur Bindung von Klassen mit komplexen XML-Schematypen bietet .NET Framework keine direkte dem maxOccurs-Attribut oder dem minOccurs-Attribut entsprechende Programmiersprache.

Beim Generieren von Quellcode aus einem XML-Schemadokument oder beim Durchführen der Rückübersetzung interpretiert Xsd.exe das maxOccurs-Attribut je nach dem XML-Schemadefinitionssprachen-Element unterschiedlich, in dem es angezeigt wird. In der folgenden Tabelle wird die Interpretation der einzelnen Elemente erklärt:

Element Interpretation

<element>

Mögliche Werte:

  • 1: Xsd.exe erzeugt ein Feld, dessen Typ dem Datentyp des Elements entspricht.

  • 0: Xsd.exe verarbeitet den Wert 0 nicht und behandelt stattdessen den Wert als Standardwert 1.

  • unbounded: Xsd.exe erzeugt ein Feld, das ein Array des Typs entsprechend dem Datentyp des Elements ist.

  • Jede ganze Zahl über 1: Wie beim Wert unbounded erzeugt Xsd.exe ein Feld, das ein Array des Typs entsprechend dem Datentyp des Elements ist. Sie können einen größeren Wert als 1 erzwingen, indem Sie ein XML-Dokument mit der XmlValidatingReader-Klasse anhand eines XML-Schemadokuments überprüfen, das durch das SOM dargestellt wird.

<group>

Beim <group>-Element wird ein maxOccurs-Wert von 0 von Xsd.exe als 1 interpretiert. Ein maxOccurs-Wert größer als 1 wird als nicht gebunden interpretiert.

Xsd.exe verarbeitet den maxOccurs="unbounded"-Wert für das <group>-Element jedoch standardmäßig so, als ob jedes untergeordnete Element mit maxOccurs="unbounded" angegeben wurde. Wenn z. B. jedes untergeordnete Element des <group><element>-Elements ein -Element ist, ist jedes in der darauf folgenden Klasse erstellte Feld ein Array des entsprechenden Typs.

Damit Schemas, die Gruppen mit maxOccurs größer als 1 enthalten, ordnungsgemäß importiert werden, sollten Sie Xsd.exe mit der Befehlzeilenoption /order aufrufen. Bei Angabe dieser Option wird die gesamte Gruppe als einzelnes Array importiert, in dem das XmlElementAttribute-Attribute auf jedes Element der Gruppe angewendet wurde. Der Typ des Arrays wird durch die Typen der Elemente bestimmt, wobei als Typ der am stärksten abgeleitete Typ festgelegt wird, dem alle Elemente zugewiesen werden können. Das heißt, wenn eine Gruppe Elemente der Typen Type1 und Type2 enthält, die beide von TypeBase abgeleitet sind, ist das Array vom Typ TypeBase. Wenn kein gemeinsamer Basistyp vorhanden ist, ist das Array vom Typ Object. Ein betreffendes Beispiel finden Sie im <sequence>-Beispiel am Ende dieses Themas.

<all>

Für das maxOccurs-Attribut ist ausschließlich der Wert 1 gültig. Xsd.exe gibt bei einem ungültigen Wert eine Fehlermeldung aus.

<any>

Mögliche Werte:

  • 1: Xsd.exe erstellt ein Feld vom Typ System.Xml.XmlElement mit einem System.Xml.Serialization.XmlAnyElementAttribute-Attribut. Über dieses Attribut kann eine Klasse beliebige XML-Elemente darstellen, ohne diese an nicht XML-spezifische Typen zu binden, die über andere mögliche Klassenmember angegeben werden.

  • 0: Xsd.exe verarbeitet den Wert 0 nicht. Stattdessen wird der Wert als Standardwert 1 verarbeitet.

  • unbounded: Xsd.exe erstellt ein XmlElement-Array mit einem XmlAnyElement-Attribut.

  • Eine beliebige ganze Zahl größer als 1: Wie beim Wert unbounded erstellt Xsd.ein XmlElement-Array mit einem XmlAnyElement-Attribut. Sie können einen größeren Wert als 1 erzwingen, indem Sie ein XML-Dokument mit der XmlValidatingReader-Klasse anhand eines XML-Schemadokuments überprüfen, das durch das SOM dargestellt wird.

<choice>

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 einzelnen Elemente müssen sich im Elementnamen unterscheiden. Optional können sie sich nach Typ und bei Gruppen nach Nummer unterscheiden. Weitere Informationen finden Sie in den Ausführungen zum <choice>-Element.

Bei den Elementen <choice>, <element> und <any> wird der Wert 0 für maxOccurs von Xsd.exe als 1 und ein maxOccurs-Wert größer als 1 als unbounded interpretiert.

Bei Angabe des Werts 1 erstellt Xsd.exe ein Feld vom allgemeinen Typ oder einem allgemeinen Basistyp. Bei jeder Auswahloption wird ein Attribut des Typs XmlElementAttribute auf das Feld angewendet. Wenn sich die Auswahloptionen nicht nach Typ unterscheiden, generiert Xsd.exe ein Attribut vom Typ XmlChoiceIdentifierAttribute, wobei ein zweites Feld mit einem Enumerationstyp angegeben wird, der die einzelnen Optionen darstellt. Dieses Verfahren und die entsprechenden Beispiele werden in den Ausführungen zum <choice>-Element ausführlich erläutert.

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.

<Reihenfolge>

Wie bei den meisten vorhergehenden Elementen wird beim <sequence>-Element der Wert 0 für maxOccurs von Xsd.exe als 1 und ein Wert größer als 1 für maxOccurs als unbounded interpretiert.

Xsd.exe verarbeitet den maxOccurs="unbounded"-Wert für das <sequence>-Element so, als ob jedes untergeordnete Element mit maxOccurs="unbounded" angegeben wurde. Wenn beispielsweise jedes untergeordnete Element des <sequence>-Elements ein <element>-Element ist, dann ist jedes in der darauf folgenden Klasse erstellte Feld ein Array des entsprechenden Typs. Xsd.exe würde diese Feldstruktur an ein <sequence maxOccurs="1"><element maxOccurs="unbounded">-Element binden, das eine angegebene Anzahl von -Elementen enthält, falls es eine Rückübersetzung in ein neues XSD-Dokument ausgeführt hat.

XmlElementAttribute-Attribute werden angewendet, ein Attribut pro Element in der Gruppe. Der Typ des Arrays wird durch die Typen der Elemente bestimmt, wobei als Typ der am stärksten abgeleitete Typ festgelegt wird, dem alle Elemente zugewiesen werden können. Das heißt, wenn eine Gruppe Elemente der Typen Type1 und Type2 enthält, die beide von TypeBase abgeleitet sind, ist das Array vom Typ TypeBase. Wenn kein gemeinsamer Basistyp vorhanden ist, ist das Array vom Typ Object. Ein verwandtes Beispiel finden Sie im <sequence>-Beispiel am Ende dieses Themas.

Beim Generieren eines XML-Schemadokuments aus einer Reihe von Klassen in einer Assembly setzt Xsd.exe die vorhergehenden Konvertierungen zurück, indem aus einer einzelnen Instanz der Wert 1 für maxOccurs und aus einem Array der Wert unbounded für maxOccurs erstellt wird.

Xsd.exe bindet den Wert unbounded für maxOccurs an ein Array und den Wert 1 für maxOccurs gegebenenfalls an das übergeordnete Element eines Arrays.

Zur Darstellung des übergeordneten Elements des Arrays wird ein Schemadatentyp erstellt, dessen Name mit ArrayOf beginnt, wenn das Standardattribut System.Xml.Serialization.XmlArrayAttribute auf das Array angewendet wird. Wird stattdessen System.Xml.Serialization.XmlElementAttribute auf ein Array angewendet, werden die Arrayelemente in einem Instanzendokument als untergeordnete Elemente des Elements angezeigt, das an die Klasse gebunden ist. Weitere Informationen zu Arraybindungen finden Sie unter Steuern der XML-Serialisierung mit Attributen.

Weitere Informationen zu Arraybindungen. Zur Erläuterung der Übersetzung eines Werts größer als 1 auf ein Array betrachten Sie den Unterschied zwischen dem Deklarieren eines Objekts eines bestimmten Typs und dem Zuweisen eines Werts (d. h. einen Speicherort im Stapel oder Heap) zu diesem Objekt. Beginnen Sie mit dem folgenden XSD-Element:

<xsd:element minOccurs="5" maxOccurs="5" name="items" type="xsd:token" />

Beim manuellen Schreiben von Code wird die Arraygröße 5 in der Typdeklaration nicht angegeben, d. h.: public string[] items. Stattdessen wird die Arraygröße beim Zuweisen eines Werts angegeben: items = new string[5].

Xsd.exe erstellt aus einem XML-Schema als Quellcode lediglich Typ- und Felddeklarationen sowie Metadaten, die als Attribute auf Typen und Felder angewendet werden können. Durch Zuweisen von Werten zu Objekten wird dieser Gültigkeitsbereich erweitert.

Sie können einen größeren Wert als 1 erzwingen, indem Sie ein XML-Dokument mit der XmlValidatingReader-Klasse mit einem durch das Schemaobjektmodell (SOM) dargestellten XML-Schemadokument überprüfen. Das SOM verwendet die System.Xml.Schema.XmlSchemaParticle.MaxOccurs-Eigenschaft und die System.Xml.Schema.XmlSchemaParticle.MaxOccursString-Eigenschaft. Beide Eigenschaften gelten für alle Elemente, die ein maxOccurs-Attribut enthalten können.

Example

Geben Sie das in einer komplexen Typdefinition enthaltene <choice>-Element für das XML-Schema ein:

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

Relevante Auszüge aus der C#-Klasse, die aus dem vorhergehenden XML-Schemadokument generiert wurde, sowie die Enumeration zur Darstellung der Elementauswahl (beim Zielnamespace http://example.org/):

    [System.Xml.Serialization.XmlElementAttribute("stringA", typeof(string))]
    [System.Xml.Serialization.XmlElementAttribute("stringB", typeof(string))]
    [System.Xml.Serialization.XmlChoiceIdentifierAttribute("ItemsElementName")]
    public string[] Items;
        
    [System.Xml.Serialization.XmlElementAttribute("ItemsElementName")]
    [System.Xml.Serialization.XmlIgnoreAttribute()]
    public ItemsChoiceType[] ItemsElementName;
...
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://example.org/", IncludeInSchema=false)]
public enum ItemsChoiceType {
    stringA,
    stringB,
}

Der komplexe Typ, der aus einer über den vorhergehenden C#-Quellcode kompilierten Klasse generiert wurde, entspricht dem ursprünglichen komplexen Typ.

<sequence>

Example

XML-Schema-Eingabedokument, das eine Sequenz mit maxOccurs größer als 1 enthält:

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
      xmlns="http://example.org/" targetNamespace="http://example.org/" elementFormDefault="qualified">
  <xsd:element name="ComplexInstance">
   <xsd:complexType>
     <xsd:sequence maxOccurs="unbounded">
       <xsd:element name="Field1" type="xsd:token"/>
       <xsd:element name="Field2" type="xsd:int" />
     </xsd:sequence>
   </xsd:complexType>
  </xsd:element>
</xsd:schema>

Anhand des vorherigen XML-Schemadokuments generierte C#-Klasse ohne Befehlszeilenoptionen:

[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://example.org/")]
[System.Xml.Serialization.XmlRootAttribute(Namespace="http://example.org/", IsNullable=false)]
public class ComplexInstance {        
    [System.Xml.Serialization.XmlElementAttribute("Field1", DataType="token")]
    public string[] Field1;
        
    [System.Xml.Serialization.XmlElementAttribute("Field2")]
    public int[] Field2;
}

Von einer Assembly, die von der vorherigen C#-Quelle kompiliert wurde, generierter komplexer XML-Schematyp:

<xs:complexType name="ComplexInstance">
  <xs:sequence>
    <xs:element minOccurs="0" maxOccurs="unbounded" name="Field1" type="xs:token" />
    <xs:element minOccurs="0" maxOccurs="unbounded" name="Field2" type="xs:int" />
  </xs:sequence>
</xs:complexType>

Wie Sie sehen, ist das resultierende Schema nicht mit dem ursprünglichen Schema äquivalent. Um Schemas mit Sequenzen mit maxOccurs größer als 1 ordnungsgemäß zu importieren, verwenden Sie die /order-Befehlszeilenoption, mit folgendem Ergebnis:

[System.Xml.Serialization.XmlTypeAttribute

(Namespace="http://example.org/")]

[System.Xml.Serialization.XmlRootAttribute

(Namespace="http://example.org/", IsNullable=false)]

public partial class ComplexInstance

{

/// <remarks/>

[System.Xml.Serialization.XmlElementAttribute

("Field1", typeof(string), DataType="token", Order=0)]

[System.Xml.Serialization.XmlElementAttribute("Field2",

typeof(int), Order=0)]

public object[] Items;

}

Mögliche enthaltene Elemente: <all>, <any>, <choice>, <element>, <group>, <sequence>

Siehe auch

Verweis

System.Xml.Schema.XmlSchemaParticle.MaxOccurs
System.Xml.Schema.XmlSchemaParticle.MaxOccursString
XmlSchemaAll
XmlSchemaAny
XmlSchemaChoice
XmlSchemaElement
XmlSchemaGroupRef
XmlSchemaSequence