1
Easy property acces (c#) to chosen object in a choice
Question asked by Bart Zuidgeest - 12/4/2020 at 2:01 PM
Answered
I'm working with an xsd containing a choice element. After I generate the classes (c# using simplified model) I get class with every option of the choice as a property. So far no problems. However as the number of options grows larger, it becomes more cumbersome to determine which choice was made. Is there a better way than using something like reflection to check which property is not null?

A property pointing to the "choosen" property would be nice.

example xsd
   <xs:choice maxOccurs="1">
        <xs:element name="option1"
                    type="type1"
                    maxOccurs="1" />
        <xs:element name="option2"
                    type="type2"
                    maxOccurs="1" />
        <xs:element name="option3"
                    type="type3"
                    maxOccurs="1" />
..........
        <xs:element name="option999"
                    type="type999"
                    maxOccurs="1" />
      </xs:choice>

results in:  

class xCt
{
    option1 {get;set;}
    option1 {get;set;}
    option1 {get;set;}
....
    option999 {get;set;}
}


Maybe my question is the result of inherently bad schema design, but I cannot figure out a different route. 
A ficticious example of this is: consider the car repair shop. Every order contains a single repair. But you can choose that one repair from many different repairs. Every repair has different requierments (paramters/suboptions). The options need to be validated so name value pairs and such generalizations are not allowed.
I thought about adding an attribute that specifies the choice made, but there seems no way to link that to the actually chosen element. So it would be up to the user to fill such a attribute correctly and I want to avoid anything that results in easy user error.

Any suggestions appreciated.

3 Replies

Reply to Thread
0
Liquid Support Replied
Employee Post Marked As Answer
Hi,

Maybe you could use the xsi:type mechanism?

For example, using the following XSD we specify an abstract base type 'RepairType' and derive other types 'RepairWheel' and 'RepairWindscreen' from this using derive by extension...

<?xml version="1.0" encoding="utf-8" ?>
<!--Created with Liquid Studio 2020 (https://www.liquid-technologies.com)-->
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:complexType abstract="true" name="RepairType">
        <xs:sequence>
            <xs:element name="Cost" type="xs:string" />
        </xs:sequence>
    </xs:complexType>
    <xs:complexType name="RepairWheel">
        <xs:complexContent>
            <xs:extension base="RepairType">
                <xs:sequence>
                    <xs:element name="WheelSize" type="xs:int" />
                </xs:sequence>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>
    <xs:complexType name="RepairWindscreen">
        <xs:complexContent>
            <xs:extension base="RepairType">
                <xs:sequence>
                    <xs:element name="WindscreenSize" type="xs:int" />
                </xs:sequence>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>
    <xs:element name="Shop">
        <xs:complexType>
            <xs:sequence minOccurs="0" maxOccurs="unbounded">
                <xs:element name="Repair" type="RepairType" />
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

Then in the XML document, we can specify the type of repair using the xsi:type attribute...

<?xml version="1.0" encoding="utf-8"?>
<!-- Created with Liquid Studio 2020 (https://www.liquid-technologies.com) -->
<Shop xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="C:\Temp\RepairShop.xsd">
    <Repair xsi:type="RepairWheel">
        <Cost>123</Cost>
        <WheelSize>-259</WheelSize>
    </Repair>
    <Repair xsi:type="RepairWindscreen">
        <Cost>456</Cost>
        <WindscreenSize>-259</WindscreenSize>
    </Repair>
</Shop>

0
Bart Zuidgeest Replied
I tested you example (There are some weird ";" in there) and it seems that the intellisense actually understands this type of setup. I avoided it because I was afraid users would have to remember the proper types. I will test this further with my usecase as I seem to have underestimated the products capabilities.
1
Liquid Support Replied
Employee Post
I have removed the weird ";" from the previous post.

You can find more information about xsi:type in our XSD tutorial:


Reply to Thread