Access Elements in XSD to C# Class With xs:Choice

Viewed 27

I have read several dozen articles on the xs:Choice XSD element but cant wrap my head around how we are supposed to use the resulting class. Here is the XSD element and the class conversion from Xsd2Code++:

<xs:element name="VariantRoads">
    <xs:complexType>
        <xs:choice minOccurs="0" maxOccurs="unbounded">
            <xs:element ref="Variant" minOccurs="0"/>
            <xs:element ref="DepVariant"/>
            <xs:element ref="ArrVariant"/>
        </xs:choice>
    </xs:complexType>
</xs:element>


[XmlArrayItemAttribute("ArrVariant", typeof(ArrVariantType), IsNullable = false)]
[XmlArrayItemAttribute("DepVariant", typeof(DepVariantType), IsNullable = false)]
[XmlArrayItemAttribute("Variant", typeof(VariantType), IsNullable = false)]
public object[] VariantRoads
{
    get
    {
        return _variantRoads;
    }
    set
    {
        _variantRoads = value;
    }
}

So that compiles and now I am ready to start populating my main class.

BaseRoadType brd = new BaseRoadType();
brd.VariantRoads = = new object[3]; // not sure how to initialize
brd.VariantRoads[0] = ??? // how do I assign my property 

I am just really lost on how I should populate the VariantRoads class and then read it later and determine what choice was made.

1 Answers

The XmlArrayItemAttribute attributes at the top of the public object[] VariantRoads declaration gives you type hints that are acceptable element values of the array.

An xs:choice is meant to model just one of multiple possibilities - but there's also the maxOccurs="unbounded" attribute set on the choice definition, which turns the type declaration to an object array object[].

The choice definition reads in plain English as basically 'zero or many choices of ("ArrVariant", "DepVariant", "Variant") elements'

So this is acceptable:

BaseRoadType brd = new BaseRoadType();
brd.VariantRoads = new object[1] {
  new ArrVariant()
};

Andt this is too:

brd.VariantRoads = new object[3] {
  new Variant(), new ArrVariant(), new DepVariant(),
};

And also multiple instances of the same type:

brd.VariantRoads = new object[2] {
  new ArrVariant(), new ArrVariant(),
};

Because each element in the array represents your 'choice' of the possible 3, the maxOccurs="unbounded" also means you can have more than one choice (hence the array).

To take it further, if the choice definition didn't have the maxOccurs="unbounded", the generated code would probably look like this:

[XmlArrayItemAttribute("ArrVariant", typeof(ArrVariantType), IsNullable = false)]
[XmlArrayItemAttribute("DepVariant", typeof(DepVariantType), IsNullable = false)]
[XmlArrayItemAttribute("Variant", typeof(VariantType), IsNullable = false)]
public object VariantRoad { get; set; }

Meaning you could only have one choice.

Related