Issue with nested xs:choice an xs:sequence

Aug 24, 2010 at 10:22 AM

First of all, this is a great program! Thank you very much. It is the only code generator that I found that processes the schema from my client (nearly) correct. The core problem of the schema I have to work with is a nested xs:choice with an xs:sequence. I assembled a test solution and it uses a schema like this:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="ChoiceList"
    targetNamespace="http://test"
    elementFormDefault="qualified"
    xmlns="http://test"
    xmlns:mstns="http://test"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
>

  <xs:element name="RootArray">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="Row" maxOccurs="unbounded" type="ChoicesArray">
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

  <xs:complexType name="ChoicesArray">
    <xs:choice>
      <xs:sequence>
        <xs:element name="First" type="xs:int" minOccurs="0"/>
        <xs:element name="Second" type="xs:string" minOccurs="0"/>
      </xs:sequence>
      <xs:sequence>
        <xs:element name="Third" type="xs:int" minOccurs="0"/>
        <xs:element name="Forth" type="xs:string" minOccurs="0"/>
      </xs:sequence>
    </xs:choice>
  </xs:complexType>
</xs:schema>

Using the following options and code I can deserialize the XML perfectly:

//    <NameSpace>Array</NameSpace><Collection>Array</Collection><codeType>CSharp</codeType><EnableDataBinding>False</EnableDataBinding><EnableLazyLoading>False</EnableLazyLoading><TrackingChangesEnable>False</TrackingChangesEnable><GenTrackingClasses>False</GenTrackingClasses><HidePrivateFieldInIDE>True</HidePrivateFieldInIDE><EnableSummaryComment>False</EnableSummaryComment><VirtualProp>False</VirtualProp><IncludeSerializeMethod>True</IncludeSerializeMethod><UseBaseClass>False</UseBaseClass><GenBaseClass>False</GenBaseClass><GenerateCloneMethod>False</GenerateCloneMethod><GenerateDataContracts>False</GenerateDataContracts><CodeBaseTag>Net35</CodeBaseTag><SerializeMethodName>Serialize</SerializeMethodName><DeserializeMethodName>Deserialize</DeserializeMethodName><SaveToFileMethodName>SaveToFile</SaveToFileMethodName><LoadFromFileMethodName>LoadFromFile</LoadFromFileMethodName><GenerateXMLAttributes>True</GenerateXMLAttributes><AutomaticProperties>True</AutomaticProperties><GenerateShouldSerialize>False</GenerateShouldSerialize><DisableDebug>True</DisableDebug><PropNameSpecified>Default</PropNameSpecified><CustomUsings></CustomUsings><ExcludeIncludedTypes>False</ExcludeIncludedTypes><EnableInitializeFields>True</EnableInitializeFields>
var rootArray = Array.RootArray.Deserialize("<RootArray xmlns='http://test'><Row><First id='1'>1</First><Second id='22'>2</Second></Row><Row><Third id='3'>3</Third></Row></RootArray>");

But what I really want to have is a List as collection type, so I selected it accordingly (with another XSD with same structure:)

 
// <NameSpace>List</NameSpace><Collection>List</Collection><codeType>CSharp</codeType><EnableDataBinding>False</EnableDataBinding><EnableLazyLoading>False</EnableLazyLoading><TrackingChangesEnable>False</TrackingChangesEnable><GenTrackingClasses>False</GenTrackingClasses><HidePrivateFieldInIDE>True</HidePrivateFieldInIDE><EnableSummaryComment>False</EnableSummaryComment><VirtualProp>False</VirtualProp><IncludeSerializeMethod>True</IncludeSerializeMethod><UseBaseClass>False</UseBaseClass><GenBaseClass>False</GenBaseClass><GenerateCloneMethod>False</GenerateCloneMethod><GenerateDataContracts>False</GenerateDataContracts><CodeBaseTag>Net35</CodeBaseTag><SerializeMethodName>Serialize</SerializeMethodName><DeserializeMethodName>Deserialize</DeserializeMethodName><SaveToFileMethodName>SaveToFile</SaveToFileMethodName><LoadFromFileMethodName>LoadFromFile</LoadFromFileMethodName><GenerateXMLAttributes>True</GenerateXMLAttributes><AutomaticProperties>True</AutomaticProperties><GenerateShouldSerialize>False</GenerateShouldSerialize><DisableDebug>True</DisableDebug><PropNameSpecified>Default</PropNameSpecified><CustomUsings></CustomUsings><ExcludeIncludedTypes>False</ExcludeIncludedTypes><EnableInitializeFields>True</EnableInitializeFields> var rootList = List.RootList.Deserialize("<RootList xmlns='http://test'><Row><First id='1'>1</First><Second id='22'>2</Second></Row><Row><Third id='3'>3</Third></Row></RootList>");

Now the deserialization throws an error:

{"Type of choice identifier 'ItemsElementName' is inconsistent with type of 'Items'. Please use array of System.Collections.Generic.List`1[[List.ItemsChoiceType, Xsd2CodeTest, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]."}

I believe this is an issue from .NET that the use of the XmlChoiceIdentifierAttribute attribute needs an array instead of something like a List<>. :-(

My current workaround is to use List as collection type, and manually change the List to an [] at a few places. I'd love to e.g. have an option to fall back to [] for some elements or let the xsd2code detect the problem and use [] for these cases.

Of course I might be wrong alltogether, so if someone has a hint....

thanks,

Eljakim

PS: I have assembled a VS2010 solution, but I do not find a way to upload it here.