我有一个XSD定义如下(我匿名了类型名称),你总是得到一个<response>
元素:
<xsd:element name="response">
<xsd:complexType>
<xsd:annotation>
<xsd:documentation>
Root element of the all response XML's
</xsd:documentation>
</xsd:annotation>
<xsd:sequence>
<xsd:choice>
<xsd:choice>
<xsd:element name="TypeA" type="TypeAType" />
<xsd:element name="TypeB" type="TypeBType" />
<xsd:element name="TypeC" type="TypeCType" />
</xsd:choice>
<xsd:element name="error" type="xsd:string">
<xsd:annotation>
<xsd:documentation>
In case of error this will contain detailed error information
and no other sibling elements will exist.
If the request is successful this element will not exist.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
</xsd:choice>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
当我使用XSD.exe(Visual 2013)自动生成C#代码时,我得到了这个:
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.33440")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
[System.Xml.Serialization.XmlRootAttribute("response", Namespace="", IsNullable=false)]
public partial class response {
private object itemField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("TypeA", typeof(TypeAType))]
[System.Xml.Serialization.XmlElementAttribute("TypeB", typeof(TypeBType))]
[System.Xml.Serialization.XmlElementAttribute("TypeC", typeof(TypeCType))]
[System.Xml.Serialization.XmlElementAttribute("error", typeof(string))]
public object Item {
get {
return this.itemField;
}
set {
this.itemField = value;
}
}
}
只有一个Object
字段。甚至没有枚举/值来告诉我它对应的元素/类型,我必须检查类型或强制转换。在过去,XSD.exe生成了更加用户友好的东西。例如每种类型的字段TypeAType typeAField; string errorField;
等
我的主要抱怨是error
只是一个字符串。因此,我判断是否存在错误的唯一方法是查看Item
是否为string
。这真的很笨重。
任何人都可以建议为什么XSD.exe在这个XSD上以这种方式运行,并且如果有办法哄它,否则。
答案 0 :(得分:1)
如果choice
中元素的类型不同,xsd.exe只生成类型为object
的单个属性或它们的公共基类(如果有)。如果某些元素具有相同的类型,则xsd.exe会生成一个附加字段和一个用于区分元素的枚举。这是MSDN上的文档:Choice Element Binding Support
我认为按类型区分更加惯用,更多DRY(额外的枚举只会重复已经在.NET类型系统中的信息)并且更容易使用(只需设置元素&#39; s属性而不是其他类型属性,加if (x.Item is string) ...
似乎比if (x.ItemElementName == ItemChoiceType.TypeA) ...
更容易。但是如果你真的想要枚举,你可以在choice
中引入一个额外的虚拟元素,它与其他选项的类型相同。