Reputation: 63710
I have an XSD defined as follows (I anonymised the type names), you always get back a single <response>
element:
<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>
When I autogenerate C# code using XSD.exe (Visual 2013) I just get this:
[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;
}
}
}
Just a single Object
field. Not even an enum/value to tell me which element/type it corresponds to, I have to inspect the type or cast. In the past XSD.exe has generated something much more user-friendly. e.g. a field of each type TypeAType typeAField; string errorField;
etc
My main complaint here is that error
is just a string. So the only way for me to tell if there is an error is to see if Item
is a string
. Which feels really clunky.
Can anyone suggest why XSD.exe is working this way with this XSD and if there is a way to coax it otherwise.
Upvotes: 2
Views: 869
Reputation: 3386
If the types of the elements in the choice
differ, xsd.exe generates just a single property of type object
or of their common base class if they have one. If some of the elements have the same type, xsd.exe generates an additional field and an enum to differentiate between the elements. Here's the documentation on MSDN: Choice Element Binding Support
I believe the differentiation by type is more idiomatic, more DRY (an additional enum would just repeat the information that's already in the .NET type system) and easier to use (just set the element's property and not an additional type property, plus if (x.Item is string) ...
seems easier than if (x.ItemElementName == ItemChoiceType.TypeA) ...
). But if you really want to have the enum you could introduce an additional dummy element into the choice
that has the same type as one of the other options.
Upvotes: 1