本主题专门介绍一项旧有技术。现在应通过使用以下链接来创建 XML Web 服务和 XML Web 服务客户端: Windows Communication Foundation.
.NET Framework 为 <choice> 元素提供绑定支持。
如果各个 choice 元素的类型和名称均不相同,则 Xsd.exe 仅将 XmlElementAttribute 特性应用于公共成员。如果它们只是名称不同,则 Xsd.exe 还将应用 XmlChoiceIdentifierAttribute,并添加用来进行选择的额外逻辑。
说明
<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 实例;另一个特性用来将该类型序列化为 System.Decimal 实例。在本例中,XmlSerializer 类使用此时分配给该对象的类型。在对 int
对象进行如下分配时,使用 <numberA>
元素:
Item = 1;
只要选项有不同的 XML 架构数据类型,Xsd.exe 就会将每个数据类型绑定到一个不同的类。由于 System.Object 是 .NET Framework 类型层次结构的根类型,因此所生成的字段总是属于一个公共基类型。Object 类是最一般的公共基类型。
如果选项全部都是从一个由 XML 架构定义的公共数据类型派生的(例如,通过 <extension> 构造),则字段类型是该数据类型的绑定。例如,假定 <choice>
元素允许在 DerivedTypeA
的 <a>
元素与 DerivedTypeB
的 <b>
元素之间进行选择,并假定这两个类型均扩展 BaseType
类型。在 C# 中,会生成下面的源代码:
[System.Xml.Serialization.XmlElementAttribute("a", typeof(DerivedTypeA))]
[System.Xml.Serialization.XmlElementAttribute("b", typeof(DerivedTypeB))]
public BaseType Item;
按名称区分
如果选项类型没有区别,则可以通过使用 XmlChoiceIdentifierAttribute 特性在创建实例文档时选择元素名称。请考虑下面的 <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
字段除了具有两个 XmlElement 特性以外,还具有一个 XmlChoiceIdentifier 特性。XmlChoiceIdentifier 特性的参数是一个枚举实例的名称。对应的枚举类型包含元素选项。枚举实例与 XmlIgnore 特性一起出现,因此它的值无法序列化。
随后,开发人员必须编写代码,以便为枚举实例分配值。下面的代码行为名为 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 |
对于 <choice> 元素,Xsd.exe 将 maxOccurs 值 对于值 对于值 请参见 maxOccurs 特性绑定支持 特性。 |
minOccurs |
当从 XML 架构文档生成源代码时,Xsd.exe 会忽略应用于 <choice> 元素的 minOccurs 特性。 当从类生成 XML 架构文档时,如果该选项表示单个对象,则 Xsd.exe 会生成一个 minOccurs 值为 请参见 minOccurs 特性绑定支持 特性。 |
可能的父元素:<choice>、<complexType>、<extension>、<group>、<restriction>、<sequence>
可能的子元素:<annotation>、<any>、<element>、<group>、<sequence>、<choice>