Choice 요소의 바인딩 지원
이 항목은 레거시 기술과 관련된 것입니다. 이제 XML Web services와 XML Web services 클라이언트는 다음을 사용하여 만들어야 합니다. Windows Communication Foundation.
.NET Framework에서는 <choice> 요소에 대한 바인딩 지원을 제공합니다.
개별 choice 요소 형식이 이름별로 다를 경우 Xsd.exe는 public 멤버에 XmlElementAttribute 특성만 적용합니다. 그러나 choice 요소의 이름만 다를 경우에는 XmlChoiceIdentifierAttribute 특성도 함께 적용하며 choice 요소를 만들기 위한 다른 논리를 추가합니다.
설명
<choice> 요소는 각각 요소 또는 요소 그룹을 나타내는 두 개 이상의 자식 요소를 포함합니다. 즉, 지정된 인스턴스 문서에서 해당 엔터티 중 하나만 지정된 위치에 나타날 수 있습니다. choice 요소는 요소 이름이 달라야 합니다. 또한 choice가 그룹인 경우(예: <group> 요소)에는 요소 형식 및 요소 개수가 다를 수 있습니다.
그룹을 임의 방식으로 조합하면 예측할 수 없는 결과가 발생합니다.
형식으로 구분
가장 간단한 경우는 개별 요소의 형식과 해당 이름이 다를 때입니다. 다음 <choice> 정의를 살펴보십시오.
<xsd:choice>
<xsd:element name="numberA" type="xsd:int"/>
<xsd:element name="numberB" type="xsd:decimal"/>
</xsd:choice>
C#에서 Xsd.exe는 이 XML 스키마 내용을 다음 코드로 변환합니다.
[System.Xml.Serialization.XmlElementAttribute("numberA", typeof(int))]
[System.Xml.Serialization.XmlElementAttribute("numberB", typeof(System.Decimal))]
public object Item;
생성된 코드에서 필드에는 object 형식이 지정되지만 두 개의 XmlElementAttribute 특성도 적용됩니다. 한 특성은 형식을 int 인스턴스로 serialize하도록 지정하고 다른 특성은 형식을 System.Decimal 인스턴스로 serialize하도록 지정합니다. 이 경우 XmlSerializer 클래스는 해당 시점에 개체에 할당된 형식을 사용합니다. int
개체에 대한 다음 할당에서는 <numberA>
요소가 사용됩니다.
Item = 1;
choice 요소의 XML 스키마 데이터 형식이 다를 경우 Xsd.exe는 각 데이터 형식을 다른 클래스에 바인딩합니다. System.Object는 .NET Framework 형식 계층의 루트 형식이므로 생성된 필드는 항상 공통 기본 형식에 속합니다. Object 클래스는 가장 일반적인 공통 기본 형식에 해당합니다.
<extension> 구문을 사용하는 경우와 같이 choice가 모두 공통 XML 스키마 정의 데이터 형식에서 파생되면 필드 형식은 해당 데이터 형식의 바인딩입니다. 예를 들어, <choice>
요소가 DerivedTypeA
의 <a>
요소와 DerivedTypeB
의 <b>
요소 사이에 choice 요소를 제공하는 경우와 두 형식이 BaseType
형식을 확장하는 경우를 가정해 봅니다. C#에서 다음 소스가 생성됩니다.
[System.Xml.Serialization.XmlElementAttribute("a", typeof(DerivedTypeA))]
[System.Xml.Serialization.XmlElementAttribute("b", typeof(DerivedTypeB))]
public BaseType Item;
이름으로 구분
choice 형식이 다르지 않을 경우 인스턴스 문서 생성 시 XmlChoiceIdentifierAttribute 특성을 사용하여 choice 요소 이름이 만들어집니다. 다음 <choice>
정의를 살펴보십시오.
<xsd:choice>
<xsd:element name="stringA" type="xsd:string"/>
<xsd:element name="stringB" type="xsd:string"/>
</xsd:choice>
Xsd.exe는 이 XML 스키마 내용을 다음 코드로 변환합니다.
[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,
}
Item
필드에는 2개의 XmlElement 특성 외에도 XmlChoiceIdentifier 특성이 지정되어 있습니다. XmlChoiceIdentifier 특성의 매개 변수는 열거형 인스턴스의 이름입니다. 해당 열거형에는 choice 요소가 포함됩니다. 열거형 인스턴스는 XmlIgnore 특성과 함께 나타나므로 해당 값을 serialize할 수 없습니다.
따라서 개발자는 해당 열거형 인스턴스에 값을 할당하는 코드를 작성해야 합니다. 다음 코드는 이름이 i
인 개체에 대해 수행됩니다.
i.ItemElementName = ItemChoiceType.stringA;
자세한 내용은 XmlChoiceIdentifierAttribute 클래스를 참조하십시오.
Example
다음 입력 XML 스키마 문서에서는 <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>
앞의 XML 스키마 문서에서 생성된 C# 클래스:
[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,
}
앞의 C# 소스에서 컴파일된 어셈블리에서 생성된 주 XML 스키마 문서 (복합 형식에 대한 임의 전역 요소를 정의하기 위해 생성된 또 다른 .xsd 파일은 표시되지 않음):
<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>
가능한 특성 | 바인딩 지원 |
---|---|
id |
Xsd.exe 유틸리티는 고유 식별자를 제공하기 위한 id 특성을 무시합니다. |
maxOccurs |
Xsd.exe에서는 <choice> 요소의 경우 maxOccurs 값 해당 값이 해당 값이 MaxOccurs 특성의 바인딩 지원 특성을 참조하십시오. |
minOccurs |
XML 스키마 문서에서 소스 코드를 생성할 때 Xsd.exe는 <choice> 요소에 적용된 minOccurs 특성을 무시합니다. 클래스에서 XML 스키마 문서를 생성할 때는 choice가 단일 개체를 나타내면 minOccurs 값을 MinOccurs 특성의 바인딩 지원 특성을 참조하십시오. |
가능한 부모 요소: <choice>, <complexType>, <extension>, <group>, <restriction>, <sequence>
가능한 자식 요소: <annotation>, <any>, <element>, <group>, <sequence>, <choice>