[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue)] |
MyChoices.
<xsd:complexType name="MyChoice"> <xsd:sequence> <xsd:choice minOccurs="0" maxOccurs="1"> <xsd:element minOccurs="1" maxOccurs="1" name="ChoiceOne" type="xsd:string" /> <xsd:element minOccurs="1" maxOccurs="1" name="ChoiceTwo" type="xsd:string" /> </xsd:choice> </xsd:sequence> </xsd:complexType>
The XmlChoiceIdentifierAttribute allows you to assign a special enumeration value to each instance of the member. You must either create the enumeration yourself, or it can be generated by the the conceptual topic at MSDN: xmlschemadefinitiontoolxsdexe. The C# code below shows how the XmlChoiceIdentifierAttribute is applied to an
Item
field; the XmlChoiceIdentifierAttribute.MemberName property identifies the field that contains the enumeration that is further used to disambiguate the choice.
public class Choices{ [XmlChoiceIdentifier("itemType") public string MyChoice; // Do not serialize this next field: [XmlIgnore] public ItemChoiceType ItemType; } // Do not include this enumeration in the XML schema. [XmlType(IncludeInSchema = false)] public enum ItemChoiceType{ None, ChoiceOne, ChoiceTwo, }
When this code is in place, you can serialize and deserialize this class by setting the
itemType
field to an appropriate enumeration. For example, to serialize the
MyChoice
class, the C# code resembles the following.
Choices mc = new Choices(); mc.Choice = "Item Choice One"; mc.ItemType = ItemChoiceType.ChoiceOne;
When deserializing, the C# code might resemble the following:
MyChoice mc = (MyChoice) myXmlSerializer.Deserialize(myReader); if(mc.ItemType == ItemChoiceType.ChoiceOne) { // Handle choice one. } if(mc.ItemType == ItemChoiceType.ChoiceTwo) { // Handle choice two. } if(mc.ItemType != null) { throw CreateUnknownTypeException(mc.Item); }
There is a second scenario when the XmlChoiceIdentifierAttribute is used. In the schema below, the member is a field that returns an array of items (maxOccurs="unbounded"). The array can contain objects of the first choice ("D-a-t-a"), and of the second choice ("MoreData").
<xsd:complexType name="MyChoice"> <xsd:sequence> <xsd:choice minOccurs="0" maxOccurs="unbounded"> <xsd:element minOccurs="1" maxOccurs="1" name="D-a-t-a" type="xsd:string" /> <xsd:element minOccurs="1" maxOccurs="1" name="MoreData" type="xsd:string" /> </xsd:choice> </xsd:sequence> </xsd:complexType>
The resulting class, then, uses a field to return an array of items. For each item in the array, a corresponding
ItemChoiceType
enumeration must also be found. The matching enumerations are contained in the array returned by the
ItemsElementName
field.
public class MyChoice { [System.Xml.Serialization.XmlElementAttribute("D-a-t-a", typeof(string), IsNullable=false)] [System.Xml.Serialization.XmlElementAttribute("MoreData", typeof(string), IsNullable=false)] [System.Xml.Serialization.XmlChoiceIdentifierAttribute("ItemsElementName")] public string[] Items; [System.Xml.Serialization.XmlElementAttribute(IsNullable=false)] [System.Xml.Serialization.XmlIgnoreAttribute()] public ItemsChoiceType[] ItemsElementName; } [System.Xml.Serialization.XmlTypeAttribute(IncludeInSchema=false)] public enum ItemsChoiceType { [System.Xml.Serialization.XmlEnumAttribute("D-a-t-a")] Data, MoreData, }
When deserializing an object that includes a range of choices, use a control structure (such as an if...then...else structure) to determine how to deserialize a particular value. In the control structure, check the enumeration value and deserialize the value accordingly.
Choices
that includes two fields,
MyChoice
and
ManyChoices
. The XmlChoiceIdentifierAttribute is applied to each field specifying (through the XmlChoiceIdentifierAttribute.MemberName property) another class member that gets or sets an enumeration that disambiguates the member value. The
MyChoice
field can be set to a single value, with a corresponding enumeration member found in the
EnumType
field. The
ManyChoices
field returns an array of objects. The
ChoiceArray
field returns an array of enumeration values. For each array member in the
ManyChoices
field, a corresponding member is found in the array returned by the
ChoiceArray
field.using System; using System.Xml; using System.Xml.Serialization; using System.IO; public class Choices{ // The MyChoice field can be set to any one of // the types below. [XmlChoiceIdentifier("EnumType")] [XmlElement("Word", typeof(string))] [XmlElement("Number", typeof(int))] [XmlElement("DecimalNumber", typeof(double))] public object MyChoice; // Don't serialize this field. The EnumType field // contains the enumeration value that corresponds // to the MyChoice field value. [XmlIgnore] public ItemChoiceType EnumType; // The ManyChoices field can contain an array // of choices. Each choice must be matched to // an array item in the ChoiceArray field. [XmlChoiceIdentifier("ChoiceArray")] [XmlElement("Item", typeof(string))] [XmlElement("Amount", typeof(int))] [XmlElement("Temp", typeof(double))] public object[] ManyChoices; // TheChoiceArray field contains the enumeration // values, one for each item in the ManyChoices array. [XmlIgnore] public MoreChoices[] ChoiceArray; } [XmlType(IncludeInSchema=false)] public enum ItemChoiceType{ None, Word, Number, DecimalNumber } public enum MoreChoices{ None, Item, Amount, Temp } public class Test{ static void Main(){ Test t = new Test(); t.SerializeObject("Choices.xml"); t.DeserializeObject("Choices.xml"); } private void SerializeObject(string filename){ XmlSerializer mySerializer = new XmlSerializer(typeof(Choices)); TextWriter writer = new StreamWriter(filename); Choices myChoices = new Choices(); // Set the MyChoice field to a string. Set the // EnumType to Word. myChoices.MyChoice= "Book"; myChoices.EnumType = ItemChoiceType.Word; // Populate an object array with three items, one // of each enumeration type. Set the array to the // ManyChoices field. object[] strChoices = new object[]{"Food", 5, 98.6}; myChoices.ManyChoices=strChoices; // For each item in the ManyChoices array, add an // enumeration value. MoreChoices[] itmChoices = new MoreChoices[] {MoreChoices.Item, MoreChoices.Amount, MoreChoices.Temp}; myChoices.ChoiceArray=itmChoices; mySerializer.Serialize(writer, myChoices); writer.Close(); } private void DeserializeObject(string filename){ XmlSerializer ser = new XmlSerializer(typeof(Choices)); // A FileStream is needed to read the XML document. FileStream fs = new FileStream(filename, FileMode.Open); Choices myChoices = (Choices) ser.Deserialize(fs); fs.Close(); // Disambiguate the MyChoice value using the enumeration. if(myChoices.EnumType == ItemChoiceType.Word){ Console.WriteLine("Word: " + myChoices.MyChoice.ToString()); } else if(myChoices.EnumType == ItemChoiceType.Number){ Console.WriteLine("Number: " + myChoices.MyChoice.ToString()); } else if(myChoices.EnumType == ItemChoiceType.DecimalNumber){ Console.WriteLine("DecimalNumber: " + myChoices.MyChoice.ToString()); } // Disambiguate the ManyChoices values using the enumerations. for(int i = 0; i<myChoices.ManyChoices.Length; i++){ if(myChoices.ChoiceArray[i] == MoreChoices.Item) Console.WriteLine("Item: " + (string) myChoices.ManyChoices[i]); else if(myChoices.ChoiceArray[i] == MoreChoices.Amount) Console.WriteLine("Amount: " + myChoices.ManyChoices[i].ToString()); if(myChoices.ChoiceArray[i] == MoreChoices.Temp) Console.WriteLine("Temp: " + (string) myChoices.ManyChoices[i].ToString()); } } }
ctor #1 | Overloaded:.ctor() Default constructor. This constructor is called by derived class constructors to initialize state in this type.Initializes a new instance of the XmlChoiceIdentifierAttribute class. |
ctor #2 | Overloaded:.ctor(string name) Initializes a new instance of the XmlChoiceIdentifierAttribute class. |
MemberName | Read-write Gets or sets the name of the field that returns the enumeration to use when disambiguating types. |
TypeId (inherited from System.Attribute) |
Read-only See base class member description: System.Attribute.TypeId When implemented in a derived class, gets a unique identifier for this Attribute. |
Equals (inherited from System.Object) |
See base class member description: System.Object.Equals Derived from System.Object, the primary base class for all objects. |
GetHashCode (inherited from System.Attribute) |
See base class member description: System.Attribute.GetHashCode Returns the hash code for this instance. |
GetType (inherited from System.Object) |
See base class member description: System.Object.GetType Derived from System.Object, the primary base class for all objects. |
IsDefaultAttribute (inherited from System.Attribute) |
See base class member description: System.Attribute.IsDefaultAttribute When overridden in a derived class, returns an indication whether the value of this instance is the default value for the derived class. |
Match (inherited from System.Attribute) |
See base class member description: System.Attribute.Match When overridden in a derived class, returns a value indicating whether this instance equals a specified object. |
ToString (inherited from System.Object) |
See base class member description: System.Object.ToString Derived from System.Object, the primary base class for all objects. |
Finalize (inherited from System.Object) |
See base class member description: System.Object.Finalize Derived from System.Object, the primary base class for all objects. |
MemberwiseClone (inherited from System.Object) |
See base class member description: System.Object.MemberwiseClone Derived from System.Object, the primary base class for all objects. |
Hierarchy:
public XmlChoiceIdentifierAttribute(); |
Choices
that includes two fields,
MyChoice
and
ManyChoices
. The XmlChoiceIdentifierAttribute is applied to each field specifying (through the XmlChoiceIdentifierAttribute.MemberName property) another class member that gets or sets an enumeration that disambiguates the member value. The
MyChoice
field can be set to a single value, with a corresponding enumeration member found in the
EnumType
field. The
ManyChoices
field returns an array of objects. The
ChoiceArray
field returns an array of enumeration values. For each array member in the
ManyChoices
field, a corresponding member is found in the array returned by the
ChoiceArray
field.using System; using System.Xml; using System.Xml.Serialization; using System.IO; public class Choices{ // The MyChoice field can be set to any one of // the types below. [XmlChoiceIdentifier("EnumType")] [XmlElement("Word", typeof(string))] [XmlElement("Number", typeof(int))] [XmlElement("DecimalNumber", typeof(double))] public object MyChoice; // Don't serialize this field. The EnumType field // contains the enumeration value that corresponds // to the MyChoice field value. [XmlIgnore] public ItemChoiceType EnumType; // The ManyChoices field can contain an array // of choices. Each choice must be matched to // an array item in the ChoiceArray field. [XmlChoiceIdentifier("ChoiceArray")] [XmlElement("Item", typeof(string))] [XmlElement("Amount", typeof(int))] [XmlElement("Temp", typeof(double))] public object[] ManyChoices; // TheChoiceArray field contains the enumeration // values, one for each item in the ManyChoices array. [XmlIgnore] public MoreChoices[] ChoiceArray; } [XmlType(IncludeInSchema=false)] public enum ItemChoiceType{ None, Word, Number, DecimalNumber } public enum MoreChoices{ None, Item, Amount, Temp } public class Test{ static void Main(){ Test t = new Test(); t.SerializeObject("Choices.xml"); t.DeserializeObject("Choices.xml"); } private void SerializeObject(string filename){ XmlSerializer mySerializer = new XmlSerializer(typeof(Choices)); TextWriter writer = new StreamWriter(filename); Choices myChoices = new Choices(); // Set the MyChoice field to a string. Set the // EnumType to Word. myChoices.MyChoice= "Book"; myChoices.EnumType = ItemChoiceType.Word; // Populate an object array with three items, one // of each enumeration type. Set the array to the // ManyChoices field. object[] strChoices = new object[]{"Food", 5, 98.6}; myChoices.ManyChoices=strChoices; // For each item in the ManyChoices array, add an // enumeration value. MoreChoices[] itmChoices = new MoreChoices[] {MoreChoices.Item, MoreChoices.Amount, MoreChoices.Temp}; myChoices.ChoiceArray=itmChoices; mySerializer.Serialize(writer, myChoices); writer.Close(); } private void DeserializeObject(string filename){ XmlSerializer ser = new XmlSerializer(typeof(Choices)); // A FileStream is needed to read the XML document. FileStream fs = new FileStream(filename, FileMode.Open); Choices myChoices = (Choices) ser.Deserialize(fs); fs.Close(); // Disambiguate the MyChoice value using the enumeration. if(myChoices.EnumType == ItemChoiceType.Word){ Console.WriteLine("Word: " + myChoices.MyChoice.ToString()); } else if(myChoices.EnumType == ItemChoiceType.Number){ Console.WriteLine("Number: " + myChoices.MyChoice.ToString()); } else if(myChoices.EnumType == ItemChoiceType.DecimalNumber){ Console.WriteLine("DecimalNumber: " + myChoices.MyChoice.ToString()); } // Disambiguate the ManyChoices values using the enumerations. for(int i = 0; i<myChoices.ManyChoices.Length; i++){ if(myChoices.ChoiceArray[i] == MoreChoices.Item) Console.WriteLine("Item: " + (string) myChoices.ManyChoices[i]); else if(myChoices.ChoiceArray[i] == MoreChoices.Amount) Console.WriteLine("Amount: " + myChoices.ManyChoices[i].ToString()); if(myChoices.ChoiceArray[i] == MoreChoices.Temp) Console.WriteLine("Temp: " + (string) myChoices.ManyChoices[i].ToString()); } } }
public XmlChoiceIdentifierAttribute( |
name
public string MemberName {get; set;}
|
Choices
that includes two fields,
MyChoice
and
ManyChoices
. The XmlChoiceIdentifierAttribute is applied to each field specifying (through the XmlChoiceIdentifierAttribute.MemberName property) another class member that gets or sets an enumeration that disambiguates the member value. The
MyChoice
field can be set to a single value, with a corresponding enumeration member found in the
EnumType
field. The
ManyChoices
field returns an array of objects. The
ChoiceArray
field returns an array of enumeration values. For each array member in the
ManyChoices
field, a corresponding member is found in the array returned by the
ChoiceArray
field.using System; using System.Xml; using System.Xml.Serialization; using System.IO; public class Choices{ // The MyChoice field can be set to any one of // the types below. [XmlChoiceIdentifier("EnumType")] [XmlElement("Word", typeof(string))] [XmlElement("Number", typeof(int))] [XmlElement("DecimalNumber", typeof(double))] public object MyChoice; // Don't serialize this field. The EnumType field // contains the enumeration value that corresponds // to the MyChoice field value. [XmlIgnore] public ItemChoiceType EnumType; // The ManyChoices field can contain an array // of choices. Each choice must be matched to // an array item in the ChoiceArray field. [XmlChoiceIdentifier("ChoiceArray")] [XmlElement("Item", typeof(string))] [XmlElement("Amount", typeof(int))] [XmlElement("Temp", typeof(double))] public object[] ManyChoices; // TheChoiceArray field contains the enumeration // values, one for each item in the ManyChoices array. [XmlIgnore] public MoreChoices[] ChoiceArray; } [XmlType(IncludeInSchema=false)] public enum ItemChoiceType{ None, Word, Number, DecimalNumber } public enum MoreChoices{ None, Item, Amount, Temp } public class Test{ static void Main(){ Test t = new Test(); t.SerializeObject("Choices.xml"); t.DeserializeObject("Choices.xml"); } private void SerializeObject(string filename){ XmlSerializer mySerializer = new XmlSerializer(typeof(Choices)); TextWriter writer = new StreamWriter(filename); Choices myChoices = new Choices(); // Set the MyChoice field to a string. Set the // EnumType to Word. myChoices.MyChoice= "Book"; myChoices.EnumType = ItemChoiceType.Word; // Populate an object array with three items, one // of each enumeration type. Set the array to the // ManyChoices field. object[] strChoices = new object[]{"Food", 5, 98.6}; myChoices.ManyChoices=strChoices; // For each item in the ManyChoices array, add an // enumeration value. MoreChoices[] itmChoices = new MoreChoices[] {MoreChoices.Item, MoreChoices.Amount, MoreChoices.Temp}; myChoices.ChoiceArray=itmChoices; mySerializer.Serialize(writer, myChoices); writer.Close(); } private void DeserializeObject(string filename){ XmlSerializer ser = new XmlSerializer(typeof(Choices)); // A FileStream is needed to read the XML document. FileStream fs = new FileStream(filename, FileMode.Open); Choices myChoices = (Choices) ser.Deserialize(fs); fs.Close(); // Disambiguate the MyChoice value using the enumeration. if(myChoices.EnumType == ItemChoiceType.Word){ Console.WriteLine("Word: " + myChoices.MyChoice.ToString()); } else if(myChoices.EnumType == ItemChoiceType.Number){ Console.WriteLine("Number: " + myChoices.MyChoice.ToString()); } else if(myChoices.EnumType == ItemChoiceType.DecimalNumber){ Console.WriteLine("DecimalNumber: " + myChoices.MyChoice.ToString()); } // Disambiguate the ManyChoices values using the enumerations. for(int i = 0; i<myChoices.ManyChoices.Length; i++){ if(myChoices.ChoiceArray[i] == MoreChoices.Item) Console.WriteLine("Item: " + (string) myChoices.ManyChoices[i]); else if(myChoices.ChoiceArray[i] == MoreChoices.Amount) Console.WriteLine("Amount: " + myChoices.ManyChoices[i].ToString()); if(myChoices.ChoiceArray[i] == MoreChoices.Temp) Console.WriteLine("Temp: " + (string) myChoices.ManyChoices[i].ToString()); } } }
public virtual object TypeId {get;}
|
~XmlChoiceIdentifierAttribute(); |
public override int GetHashCode(); |
public Type GetType(); |
public virtual bool IsDefaultAttribute(); |
The implementation of this method in a derived class compares the value of this instance to a standard, default value obtained by some means, then returns a Boolean value that indicates whether the value of this instance is equal to the standard. The standard value is typically coded as a constant in the implementation, or stored programmatically in a field used by the implementation.
obj
protected object MemberwiseClone(); |
public virtual string ToString(); |