XmlChoiceIdentifierAttribute クラス
列挙体を使用して、メンバを明確に区別できるようにすることを指定します。
この型のすべてのメンバの一覧については、XmlChoiceIdentifierAttribute メンバ を参照してください。
System.Object
System.Attribute
System.Xml.Serialization.XmlChoiceIdentifierAttribute
<AttributeUsage(AttributeTargets.Property Or AttributeTargets.Field _
Or AttributeTargets.Parameter Or AttributeTargets.ReturnValue)>
Public Class XmlChoiceIdentifierAttribute Inherits Attribute
[C#]
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field
| AttributeTargets.Parameter | AttributeTargets.ReturnValue)]
public class XmlChoiceIdentifierAttribute : Attribute
[C++]
[AttributeUsage(AttributeTargets::Property |
AttributeTargets::Field | AttributeTargets::Parameter |
AttributeTargets::ReturnValue)]
public __gc class XmlChoiceIdentifierAttribute : public Attribute
[JScript]
public
AttributeUsage(AttributeTargets.Property | AttributeTargets.Field |
AttributeTargets.Parameter | AttributeTargets.ReturnValue)
class XmlChoiceIdentifierAttribute extends Attribute
スレッドセーフ
この型の public static (Visual Basicでは Shared) のすべてのメンバは、マルチスレッド操作で安全に使用できます。インスタンスのメンバの場合は、スレッドセーフであるとは限りません。
解説
xsi:choice という名前の XML スキーマ要素定義を使用すると、その子のうちの 1 つだけをインスタンスに含めることのできる (maxoccurs = 1) 複合要素を定義できます。インスタンスに含めることのできる子は、いくつかの型のいずれかになり、その名前もいくつかの名前のうちの 1 つになります。それぞれの名前は特定の型に関連付けられますが、いくつかの名前を同じ型に関連付けることもできます。したがって、このような要素のインスタンスはあいまいになります。このようなあいまいな要素の例として、 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>
XmlChoiceIdentifierAttribute を使用すると、メンバの各インスタンスに特定の列挙値を割り当てることができます。列挙体は独自に作成するか、 XML スキーマ定義ツール (Xsd.exe) を使用して作成する必要があります。下の C# コードでは、 XmlChoiceIdentifierAttribute を Item
フィールドに適用する方法を示しています。その MemberName プロパティには、メンバのインスタンスを明確に区別するために使用する列挙体を格納しているフィールドが指定されています。
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,
}
このコードを正しい場所に記述すると、 itemType
フィールドに適切な列挙体を設定することによって、このクラスをシリアル化および逆シリアル化できます。たとえば、 MyChoice
クラスをシリアル化するための C# コードは、次のようになります。
Choices mc = new Choices();
mc.Choice = "Item Choice One";
mc.ItemType = ItemChoiceType.ChoiceOne;
逆シリアル化する場合の C# コードは、次のようになります。
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);
}
XmlChoiceIdentifierAttribute の用途は、もう 1 つあります。次のスキーマでは、メンバは、項目の配列 (maxOccurs="unbounded") を返すフィールドです。この配列には、最初の要素 ("D-a-t-a") と 2 番目の要素 ("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>
結果として生成されたクラスは、このフィールドを使用して項目の配列を返します。配列の各項目について、 ItemChoiceType
列挙体の値が対応している必要があります。この対応している列挙値が、 ItemsElementName
フィールドによって返される配列に格納されています。
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,
}
一定範囲内の複数の choice 要素を含んでいるオブジェクトを逆シリアル化するときは、制御構造 (if...then...else 構造など) を使用して、特定の値を逆シリアル化する方法を決定します。この制御構造では、列挙値を調べ、その結果に基づいて値を逆シリアル化します。
使用例
[Visual Basic, C#, C++] MyChoice
と ManyChoices
という 2 つのフィールドを含んでいる Choices
という名前のクラスをシリアル化する例を次に示します。各フィールドに XmlChoiceIdentifierAttribute が適用されており、これらのフィールドは、 MemberName プロパティを使用して、それぞれの値を明確に区別するための列挙体を取得または設定する別のクラス メンバを指定しています。 MyChoice
フィールドには、対応する列挙体メンバが EnumType
フィールド内に存在している単一の値を設定できます。 ManyChoices
フィールドは、オブジェクトの配列を返します。 ChoiceArray
フィールドは、列挙値の配列を返します。 ManyChoices
フィールドの各配列メンバに対応するメンバが、 ChoiceArray
フィールドによって返される配列の中に見つかります。
Imports System
Imports System.Xml
Imports System.Xml.Serialization
Imports System.IO
Public Class Choices
' The MyChoice field can be set to any one of
' the types below.
<XmlChoiceIdentifier("EnumType"), _
XmlElement("Word", GetType(String)), _
XmlElement("Number", GetType(Integer)), _
XmlElement("DecimalNumber", GetType(double))> _
Public MyChoice As Object
' Don't serialize this field. The EnumType field
' contains the enumeration value that corresponds
' to the MyChoice field value.
<XmlIgnore> _
Public EnumType As ItemChoiceType
'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", GetType(string)), _
XmlElement("Amount", GetType(Integer)), _
XmlElement("Temp", GetType(double))> _
Public ManyChoices() As Object
' TheChoiceArray field contains the enumeration
' values, one for each item in the ManyChoices array.
<XmlIgnore> _
Public ChoiceArray() As MoreChoices
End Class
<XmlType(IncludeInSchema:=false)> _
Public Enum ItemChoiceType
None
Word
Number
DecimalNumber
End Enum
<XmlType(IncludeInSchema:=false)> _
Public Enum MoreChoices
None
Item
Amount
Temp
End Enum
Public Class Test
Shared Sub Main()
Dim t As Test = New Test()
t.SerializeObject("Choices.xml")
t.DeserializeObject("Choices.xml")
End Sub
private Sub SerializeObject(filename As string)
Dim mySerializer As XmlSerializer = _
New XmlSerializer(GetType(Choices))
Dim writer As TextWriter = New StreamWriter(filename)
Dim myChoices As Choices = 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.
Dim strChoices () As Object = New object(){"Food", 5, 98.6}
myChoices.ManyChoices=strChoices
' For each item in the ManyChoices array, add an
' enumeration value.
Dim itmChoices () As MoreChoices = New MoreChoices() _
{MoreChoices.Item, _
MoreChoices.Amount, _
MoreChoices.Temp}
myChoices.ChoiceArray=itmChoices
mySerializer.Serialize(writer, myChoices)
writer.Close()
End Sub
private Sub DeserializeObject(filename As string)
Dim ser As XmlSerializer = New XmlSerializer(GetType(Choices))
' A FileStream is needed to read the XML document.
Dim fs As FileStream = New FileStream(filename, FileMode.Open)
Dim myChoices As Choices = CType(ser.Deserialize(fs), Choices)
fs.Close()
' Disambiguate the MyChoice value Imports the enumeration.
if myChoices.EnumType = ItemChoiceType.Word Then
Console.WriteLine("Word: " & _
myChoices.MyChoice.ToString())
else if myChoices.EnumType = ItemChoiceType.Number Then
Console.WriteLine("Number: " & _
myChoices.MyChoice.ToString())
else if myChoices.EnumType = ItemChoiceType.DecimalNumber Then
Console.WriteLine("DecimalNumber: " & _
myChoices.MyChoice.ToString())
End If
' Disambiguate the ManyChoices values Imports the enumerations.
Dim i As Integer
for i = 0 to myChoices.ManyChoices.Length -1
if myChoices.ChoiceArray(i) = MoreChoices.Item Then
Console.WriteLine("Item: " + _
myChoices.ManyChoices(i).ToString())
else if myChoices.ChoiceArray(i) = MoreChoices.Amount Then
Console.WriteLine("Amount: " + _
myChoices.ManyChoices(i).ToString())
else if (myChoices.ChoiceArray(i) = MoreChoices.Temp)
Console.WriteLine("Temp: " + _
myChoices.ManyChoices(i).ToString())
End If
Next i
End Sub
End Class
[C#]
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());
}
}
}
[C++]
#using <mscorlib.dll>
#using <System.dll>
#using <System.xml.dll>
using namespace System;
using namespace System::Xml;
using namespace System::Xml::Serialization;
using namespace System::IO;
[XmlType(IncludeInSchema=false)]
public __value enum ItemChoiceType
{
None,
Word,
Number,
DecimalNumber
};
public __value enum MoreChoices
{
None,
Item,
Amount,
Temp
};
public __gc class Choices
{
public:
// The MyChoice field can be set to any one of
// the types below.
[XmlChoiceIdentifier("EnumType")]
[XmlElement("Word", __typeof(String))]
[XmlElement("Number", __typeof(Int32))]
[XmlElement("DecimalNumber", __typeof(Double))]
Object* MyChoice;
// Don't serialize this field. The EnumType field
// contains the enumeration value that corresponds
// to the MyChoice field value.
[XmlIgnore]
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(Int32))]
[XmlElement("Temp", __typeof(Double))]
Object* ManyChoices[];
// TheChoiceArray field contains the enumeration
// values, one for each item in the ManyChoices array.
[XmlIgnore]
MoreChoices ChoiceArray[];
};
void SerializeObject(String* filename);
void DeserializeObject(String* filename);
int main(){
SerializeObject(S"Choices.xml");
DeserializeObject(S"Choices.xml");
}
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= S"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[] = {S"Food", __box(5), __box(98.6) };
myChoices->ManyChoices = strChoices;
// For each item in the ManyChoices array, add an
// enumeration value.
MoreChoices itmChoices[] =
{MoreChoices::Item,
MoreChoices::Amount,
MoreChoices::Temp};
myChoices->ChoiceArray = itmChoices;
mySerializer->Serialize(writer, myChoices);
writer->Close();
}
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 = __try_cast<Choices*>( ser->Deserialize(fs));
fs->Close();
// Disambiguate the MyChoice value using the enumeration.
if(myChoices->EnumType == ItemChoiceType::Word)
{
Console::WriteLine( S"Word: {0}", myChoices->MyChoice->ToString());
}
else if( myChoices->EnumType == ItemChoiceType::Number)
{
Console::WriteLine( S"Number: {0}", myChoices->MyChoice->ToString());
}
else if( myChoices->EnumType == ItemChoiceType::DecimalNumber)
{
Console::WriteLine( S"DecimalNumber: {0}", 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( S"Item: {0}", myChoices->ManyChoices[i]);
else if ( myChoices->ChoiceArray[i] == MoreChoices::Amount )
Console::WriteLine( S"Amount: ", myChoices->ManyChoices[i]->ToString());
if(myChoices->ChoiceArray[i] == MoreChoices::Temp)
Console::WriteLine(S"Temp: {0}" , myChoices->ManyChoices[i]->ToString());
}
}
[JScript] JScript のサンプルはありません。Visual Basic、C#、および C++ のサンプルを表示するには、このページの左上隅にある言語のフィルタ ボタン をクリックします。
必要条件
名前空間: System.Xml.Serialization
プラットフォーム: Windows 98, Windows NT 4.0, Windows Millennium Edition, Windows 2000, Windows XP Home Edition, Windows XP Professional, Windows Server 2003 ファミリ, .NET Compact Framework - Windows CE .NET
アセンブリ: System.Xml (System.Xml.dll 内)
参照
XmlChoiceIdentifierAttribute メンバ | System.Xml.Serialization 名前空間