Prise en charge de la liaison de l'élément Choice
Le .NET Framework prend en charge la liaison pour l'élément <choice>.
Si les noms et les types des éléments choice individuels diffèrent, Xsd.exe applique uniquement les attributs XmlElementAttribute à un membre public. Si seul leur nom diffère, Xsd.exe applique en plus un attribut XmlChoiceIdentifierAttribute et ajoute une logique supplémentaire pour la sélection.
Explication
L'élément <choice> contient deux éléments enfants ou plus, qui représentent chacun un élément ou un groupe d'éléments. Il indique que, dans une instance de document donnée, une seule de ces entités peut apparaître dans la position spécifiée. Les éléments choice doivent différer par nom d'élément. Ils peuvent également différer par type d'élément et, si l'élément choice est un regroupement (tel qu'un élément <group>), par nombre d'éléments
Des combinaisons ambiguës de groupes entraînent des résultats imprévisibles.
Différenciation par type
Le cas le plus simple survient lorsque les noms et les types des éléments individuels diffèrent. Regardez la définition <choice> suivante :
<xsd:choice>
<xsd:element name="numberA" type="xsd:int"/>
<xsd:element name="numberB" type="xsd:decimal"/>
</xsd:choice>
En C#, Xsd.exe traduirait ce contenu de schéma XML en code, comme suit :
[System.Xml.Serialization.XmlElementAttribute("numberA", typeof(int))]
[System.Xml.Serialization.XmlElementAttribute("numberB", typeof(System.Decimal))]
public object Item;
Dans le code généré, le type object est attribué au champ, mais celui-ci possède également deux attributs XmlElementAttribute. Un attribut demande de sérialiser le type vers une instance int ; l'autre demande de sérialiser le type vers une instance System.Decimal. Dans ce cas, la classe XmlSerializer utilise le type assigné à l'objet à ce moment. Avec l'assignation suivante à un objet int
, l'élément <numberA>
est utilisé :
Item = 1;
Chaque fois que les éléments choice ont des types de données de schéma XML différents, Xsd.exe lie chacun des types de données à une classe différente. Dans la mesure où System.Object est le type racine de la hiérarchie de types .NET Framework, le champ généré appartient toujours à un type de base commun. La classe d'objet est le type de base commun le plus générique.
Lorsque les choix sont tous dérivés d'un type de données de schéma XML commun, par exemple via la construction <extension>, le type de champ est une liaison de ce type de données. Par exemple, supposons qu'un élément <choice>
propose un choix entre l'élément <a>
de DerivedTypeA
et l'élément <b>
de DerivedTypeB
, et que ces types étendent le type BaseType
. En C#, la source suivante est générée :
[System.Xml.Serialization.XmlElementAttribute("a", typeof(DerivedTypeA))]
[System.Xml.Serialization.XmlElementAttribute("b", typeof(DerivedTypeB))]
public BaseType Item;
Différenciation par nom
Si les types de choix ne diffèrent pas, le choix du nom de l'élément lors de la création d'une instance de document est effectué à l'aide de l'attribut XmlChoiceIdentifierAttribute. Regardez la définition <choice>
suivante :
<xsd:choice>
<xsd:element name="stringA" type="xsd:string"/>
<xsd:element name="stringB" type="xsd:string"/>
</xsd:choice>
Xsd.exe traduirait ce contenu de schéma XML en code, comme suit :
[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,
}
Le champ Item
possède un attribut XmlChoiceIdentifier, en plus des deux attributs XmlElement. Le paramètre pour l'attribut XmlChoiceIdentifier est le nom d'une instance d'énumération. Le type énumération correspondant contient les choix d'élément. L'instance d'énumération apparaît avec un attribut XmlIgnore, de sorte que sa valeur ne peut pas être sérialisée.
Le développeur doit ensuite écrire du code pour assigner une valeur à l'instance d'énumération. La ligne suivante réalise cette opération pour un objet nommé i
:
i.ItemElementName = ItemChoiceType.stringA;
Pour plus d'informations, consultez la classe XmlChoiceIdentifierAttribute.
Exemple
Le document de schéma XML d'entrée suivant montre différentes utilisations du regroupement <choice> :
<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>
Classes C# générées à partir du document de schéma XML précédent :
[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,
}
Document de schéma XML primaire généré à partir d'un assembly compilé depuis la source C# précédente. (Il existe un deuxième fichier .xsd généré afin de définir des éléments globaux arbitraires pour les types complexes ; ce fichier n'apparaît pas.)
<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>
Attributs possibles | Prise en charge de la liaison |
---|---|
id |
L'utilitaire Xsd.exe ignore l'attribut id qui a pour but de fournir un identificateur unique. |
maxOccurs |
Pour l'élément <choice>, une valeur maxOccurs de Pour une valeur de Pour la valeur Consultez l'attribut Prise en charge de la liaison de l'attribut MaxOccurs. |
minOccurs |
Lors de la génération du code source à partir d'un document de schéma XML, Xsd.exe ignore l'attribut minOccurs appliqué à l'élément <choice>. Lors de la génération d'un document de schéma XML à partir de classes, Xsd.exe génère un élément <choice> avec une valeur minOccurs de Consultez l'attribut Prise en charge de la liaison de l'attribut MinOccurs. |
Éléments parents possibles : <choice>, <complexType>, <extension>, <group>, <restriction>, <sequence>
Les éléments enfants possibles: <annotation>, <any>, <element>, <group>, <sequence>, <choice>
Voir aussi
Référence
Copyright ©2007 par Microsoft Corporation. Tous droits réservés.