Condividi tramite


Supporto dell'associazione all'attributo MaxOccurs

Questo argomento è specifico di una tecnologia legacy. Servizi Web XML e client di servizi Web XML devono essere creati attualmente tramite Windows Communication Foundation.

In .NET Framework è incluso un supporto parziale per l'associazione all'attributo maxOccurs.

Per la maggior parte degli elementi che possono specificare un attributo maxOccurs, Xsd.exe interpreta il valore 0 come 1, producendo un campo non di tipo matrice e un valore maggiore di 1 come unbounded, producendo un campo di tipo matrice. Il comportamento varia a seconda degli elementi.

Descrizione

Gli attributi maxOccurs e minOccurs limitano il numero di volte in cui è possibile visualizzare in successione l'entità specificata nella posizione corrispondente in un documento di istanza XML.

Questi attributi vengono visualizzati solo all'interno delle definizioni dei tipi complessi. Pertanto, se si desidera associare questi attributi a un elemento <element> o <group>, è necessario che l'elemento sia una dichiarazione locale o un riferimento a una dichiarazione globale e non la dichiarazione globale stessa.

Per l'associazione delle classi con i tipi complessi di XML Schema, .NET Framework non dispone di un linguaggio di programmazione diretta equivalente all'attributo maxOccurs o minOccurs.

Durante la generazione del codice sorgente da un documento XML Schema o l'esecuzione della conversione inversa, Xsd.exe interpreta l'attributo maxOccurs in modo differente a seconda dell'elemento del linguaggio di definizione XML Schema in cui viene visualizzato. Nella tabella seguente sono riportate le interpretazioni in base all'elemento:

Elemento Interpretazione

<element>

Valori possibili:

  • 1: Xsd.exe produce un campo del tipo corrispondente al tipo di dati dell'elemento.

  • 0: Xsd.exe non riesce a elaborare il valore 0 e lo considera al pari del valore 1 predefinito.

  • unbounded: Xsd.exe produce un campo che rappresenta una matrice del tipo corrispondente al tipo di dati dell'elemento.

  • Qualsiasi numero intero maggiore di 1: come per il valore unbounded, Xsd.exe produce un campo che rappresenta una matrice del tipo corrispondente al tipo di dati dell'elemento. È possibile imporre un valore maggiore di 1 convalidando un documento XML con la classe XmlValidatingReader in base a un documento XML Schema rappresentato dal modello SOM.

<gruppo>

Per l'elemento<group>, un valore maxOccurs pari a 0 viene interpretato da Xsd.exe come 1 e un valore maxOccurs maggiore di 1 viene interpretato come unbounded.

Xsd.exe, tuttavia, considera per impostazione predefinita un valore maxOccurs="unbounded" per l'elemento <group> come se ognuno degli elementi figlio venisse specificato con maxOccurs="unbounded". Se, ad esempio, ognuno dei figli dell'elemento <group><element> è un elemento , ogni campo prodotto nella classe risultante sarà una matrice del tipo appropriato.

Per importare correttamente schemi che contengono gruppi con maxOccurs maggiore di 1 si consiglia di utilizzare l'opzione della riga di comando /order con Xsd.exe. Quando viene utilizzata questa opzione, l'intero gruppo viene importato come una sola matrice XmlElementAttribute cui vengono applicati più attributi, uno per ogni elemento del gruppo. Il tipo di matrice viene determinato dai tipi di elementi. In altre parole, il tipo sarà quello derivato di livello più basso cui possono essere assegnati tutti gli elementi. Se un gruppo contiene elementi dei tipi Type1 e Type2, derivati entrambi da TypeBase, il tipo della matrice sarà TypeBase. In assenza di un tipo di base comune, il tipo della matrice sarà Object. Per un esempio correlato, vedere l'esempio <sequence> alla fine di questo argomento.

<tutte>

Qualsiasi valore per l'attributo maxOccurs diverso da 1 non è considerato valido. Xsd.exe segnala un errore per un valore non valido.

<any>

Valori possibili:

  • 1: Xsd.exe produce un campo di tipo System.Xml.XmlElement, con un attributo System.Xml.Serialization.XmlAnyElementAttribute. Tale attributo consente la rappresentazione degli elementi XML arbitrari in una classe senza associarli ai tipi non XML identificati da altri possibili membri di classe.

  • 0: Xsd.exe non riesce a elaborare il valore 0 e lo considera al pari del valore 1 predefinito.

  • unbounded: Xsd.exe produce una matrice XmlElement con un attributo XmlAnyElement.

  • Qualsiasi numero intero maggiore di 1: come per il valore unbounded, Xsd.exe produce una matrice XmlElement con un attributo XmlAnyElement. È possibile imporre un valore maggiore di 1 convalidando un documento XML con la classe XmlValidatingReader in base a un documento XML Schema rappresentato dal modello SOM.

<scelta>

L'elemento <choice> contiene due o più elementi figlio, ognuno dei quali rappresenta un elemento o un gruppo di elementi e indica che in un determinato documento di istanza è possibile visualizzare solo una di queste entità nella posizione specificata. Le scelte possono differire in base al nome dell'elemento e facoltativamente possono differire per tipo e, nel caso di un gruppo, per numero. Per ulteriori informazioni, vedere l'elemento <choice>.

Per l'elemento <choice>, come per gli elementi <element> e <any>, un valore maxOccurs pari a 0 viene interpretato da Xsd.exe come 1 e un valore maxOccurs maggiore di 1 viene interpretato come unbounded.

Per il valore 1, Xsd.exe produce un campo del tipo comune o un tipo base comune. Per ogni scelta, viene applicato un attributo del tipo XmlElementAttribute al campo. Se le scelte non differiscono in base al tipo, Xsd.exe genera un attributo del tipo XmlChoiceIdentifierAttribute, specificando un secondo campo con un tipo di enumerazione che rappresenta ognuna delle scelte. Questo meccanismo è descritto in modo dettagliato, riportando alcuni esempi, con l'elemento <choice>.

Per il valore unbounded, Xsd.exe esegue la stessa associazione, con l'eccezione che il campo generato per la scelta è una matrice di un tipo appropriato. Se tutte le scelte sono dello stesso tipo, il secondo campo (identificato dall'attributo XmlChoiceIdentifier) sarà una matrice del tipo di enumerazione generato. Ogni elemento nella seconda matrice sceglie il nome per il corrispondente elemento nella prima matrice.

<sequenza>

Per l'elemento <sequence>, come per la maggior parte degli elementi precedenti, un valore maxOccurs pari a 0 viene interpretato da Xsd.exe come 1 e un valore maxOccurs maggiore di 1 viene interpretato come unbounded.

Xsd.exe, tuttavia, considera un valore maxOccurs="unbounded" per l'elemento <sequence> come se ognuno degli elementi figlio venisse specificato con maxOccurs="unbounded". Se, ad esempio, ognuno dei figli dell'elemento <sequence> è un elemento <element>, ogni campo prodotto nella classe risultante sarà una matrice del tipo appropriato. Xsd.exe assocerebbe questa struttura di campo a un elemento <sequence maxOccurs="1"> contenente un determinato numero di elementi <element maxOccurs="unbounded"> se eseguisse una conversione inversa in un nuovo documento XSD.

Attributi XmlElementAttribute applicati, uno per ogni elemento del gruppo. Il tipo di matrice viene determinato dai tipi di elementi. In altre parole, il tipo sarà quello derivato di livello più basso cui possono essere assegnati tutti gli elementi. Se un gruppo contiene elementi dei tipi Type1 e Type2, derivati entrambi da TypeBase, il tipo della matrice sarà TypeBase. In assenza di un tipo di base comune, il tipo della matrice sarà Object. Per un esempio correlato, vedere l'esempio <sequence> alla fine di questo argomento.

Durante la generazione di un documento XML Schema da un set di classi di un assembly, Xsd.exe inverte le conversioni precedenti, producendo un valore maxOccurs pari a 1 da una singola istanza e un valore maxOccurs pari a unbounded da una matrice.

Xsd.exe associa un valore maxOccurs pari a unbounded a una matrice e un valore maxOccurs pari a 1 all'elemento padre designato di una matrice, se disponibile.

Se alla matrice viene applicata la classe System.Xml.Serialization.XmlArrayAttribute predefinita, viene creato un tipo di dati dello schema con un nome che inizia con ArrayOf per rappresentare l'elemento padre della matrice. Se invece viene applicata una classe System.Xml.Serialization.XmlElementAttribute a una matrice, gli elementi della matrice vengono visualizzati in un documento di istanza come figli dell'elemento associato alla classe. Per ulteriori informazioni sulle associazioni di matrici, vedere Controllo della serializzazione XML mediante attributi.

Ulteriori informazioni sulle associazioni di matrici. Per comprendere la conversione di un valore maggiore di 1 in una matrice, è necessario tenere presente la differenza tra la dichiarazione di un oggetto di un determinato tipo e l'assegnazione di un valore (letteralmente una posizione di memoria nello stack o nell'heap) a tale oggetto. È possibile iniziare con l'elemento XSD seguente:

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

Durante la scrittura manuale del codice, non è consigliabile esprimere la dimensione della matrice pari a cinque nella dichiarazione del tipo seguente: public string[] items. Tale dimensione può invece essere espressa durante l'assegnazione di un valore: items = new string[5].

Gli unici tipi di codice sorgente che Xsd.exe genera da uno schema XML sono le dichiarazioni di tipi e di campi e i metadati che possono essere applicati ai tipi e ai campi come attributi. L'assegnazione dei valori agli oggetti si estende oltre tale ambito.

Per imporre un valore maggiore di 1 è necessario convalidare un documento XML con la classe XmlValidatingReader in base a un documento XML Schema rappresentato dal modello SOM (Schema Object Model). Il modello SOM utilizza le proprietà System.Xml.Schema.XmlSchemaParticle.MaxOccurs e System.Xml.Schema.XmlSchemaParticle.MaxOccursString, entrambe applicabili a tutti gli elementi che possono contenere un attributo maxOccurs.

Example

Elemento <choice> dello schema XML di input all'interno di una definizione di tipo complesso:

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

Passaggi rilevanti dalla classe C# generata dal precedente documento XML Schema ed enumerazione che rappresenta le scelte degli elementi, supponendo l'utilizzo dello spazio dei nomi di destinazione 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,
}

Il tipo complesso generato da una classe compilata del codice sorgente C# precedente equivale al tipo complesso originale.

<sequence>

Example

Documento XML Schema di input contenente una sequenza con un valore maxOccurs maggiore di 1:

<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>

Classe C# generata dal precedente documento XML Schema senza opzioni della riga di comando:

[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;
}

Tipo complesso di XML Schema generato da un assembly compilato dal codice sorgente C# precedente:

<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>

Come è possibile osservare, lo schema risultante non equivale a quello originale. Per importare uno schema contenente sequenze con un valore maxOccurs maggiore di 1, utilizzare l'opzione della riga di comando /order, operazione che produrrà il seguente risultato:

[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;

}

Elementi contenitore possibili: <all>, <any>, <choice>, <element>, <group>, <sequence>

Vedere anche

Riferimento

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