Hello,
I use the last version (3.0) and I have some big issues while creating XmlSerializer with classes generated from NewsML-G2 xsd files.
http://www.iptc.org/std/NewsML-G2/NewsML-G2_2.4.zip
During the runtime, when I create the serializer, a lot of innerexception leads to the exception:
"Type of choice identifier 'ItemElementName' is inconsisitent with type of 'Item'. Please use List<>... of <namespace>.ItemChoiceType."
The thing is that the XmlChoiceIdentifierAttribute is correctly ItemElementName, and the ItemElementName is of the list<ItemChoiceType>.
Then I try to generate the same class, but this type with arrays instead of List. Then it says:
"Type ItemsChoiceType is missing enumeration value 'Items' for element 'Items' from namespace ''.""
So ok, I tried to add Items in the enum, and it goes to the next issue which is the same but in another type.
I feel this is a mistake in the class generator, but I don't really understand why it needs the type Items in the enum? Is this a bug, a mistake in the schema?
Please help!
Comments: ** Comment from web user: Andre_ **
Ok so i think i might have a good solution having spent some time reading this post and coming up with a working end result
so, after you run XSD2Code you might have a construct like this
```
'my container for my objects of type
Private itemsField As List(Of AdditionalReference3)
'my container for the ChoiceType
Private itemsElementNameField As List(Of ItemsChoiceType)
<System.Xml.Serialization.XmlElementAttribute("OthrRef", GetType(AdditionalReference3), Order:=1), _
System.Xml.Serialization.XmlElementAttribute("RltdRef", GetType(AdditionalReference3), Order:=1), _
System.Xml.Serialization.XmlChoiceIdentifierAttribute("ItemsElementName"), _
System.Xml.Serialization.XmlIgnoreAttribute()> _
Public Property Items() As List(Of AdditionalReference3)
Get
Return Me.itemsField
End Get
Set(value As List(Of AdditionalReference3))
Me.itemsField = value
End Set
End Property
<System.Xml.Serialization.XmlElementAttribute("ItemsElementName", Order:=2), _
System.Xml.Serialization.XmlIgnoreAttribute()> _
Public Property ItemsElementName() As List(Of ItemsChoiceType)
Get
Return Me.itemsElementNameField
End Get
Set(value As List(Of ItemsChoiceType))
Me.itemsElementNameField = Value
End Set
End Property
```
Then you run into problems as was correctly mentioned the xmlserialiser cannot handle collections of T when dealing with multiple choicetypes, so when you have a pattern that uses attribute XmlChoiceIdentifierAttribute that points to a collection of ItemChoiceType, you run into this issue. So we move the properties to arrays, first lets see what the code change is when building the class in code as opposed to consuming an XML doc
basically if you are late binding as I am then you move from this type of declaration and construct when building from code
```
'Assiging the choicetype
tst.OrdrInstrStsRptV03.ItemsElementName = New List(Of OrderInstructionStatusReportV03.ItemsChoiceType)
tst.OrdrInstrStsRptV03.ItemsElementName.Add(OrderInstructionStatusReportV03.ItemsChoiceType.RltdRef)
'assigning the item itself
tst.OrdrInstrStsRptV03.Items = New List(Of OrderInstructionStatusReportV03.AdditionalReference3)
tst.OrdrInstrStsRptV03.Items.Add(New OrderInstructionStatusReportV03.AdditionalReference3 With {.Ref = "123456789"})
```
To this type of code
```
'adding to or creating a new choicetype
tst.OrdrInstrStsRptV03.ItemsElementName = {OrderInstructionStatusReportV03.ItemsChoiceType.RltdRef}
'adding to or creating a new item itself
tst.OrdrInstrStsRptV03.Items = {New OrderInstructionStatusReportV03.AdditionalReference3 With {.Ref = "123456798"}}
```
__Here is the adjusted construct code of the properties, note the private variables can remain collections of T__
```
<System.Xml.Serialization.XmlElementAttribute("OthrRef", GetType(AdditionalReference3), Order:=1), _
System.Xml.Serialization.XmlElementAttribute("RltdRef", GetType(AdditionalReference3), Order:=1), _
System.Xml.Serialization.XmlChoiceIdentifierAttribute("ItemsElementName")> _
Public Property Items() As AdditionalReference3()
Get
Return Me.itemsField.ToArray
End Get
Set(value As AdditionalReference3())
If Me.itemsField Is Nothing Then
Me.itemsField = New List(Of AdditionalReference3)(value.ToList)
Else
value.All(Function(e As AdditionalReference3)
Me.itemsField.Add(e)
End Function)
End If
End Set
End Property
<System.Xml.Serialization.XmlElementAttribute("ItemsElementName", Order:=2), _
System.Xml.Serialization.XmlIgnoreAttribute()> _
Public Property ItemsElementName() As ItemsChoiceType()
Get
Return Me.itemsElementNameField.ToArray
End Get
Set(value As ItemsChoiceType())
If Me.itemsElementNameField Is Nothing Then
Me.itemsElementNameField = New List(Of ItemsChoiceType)(value.ToList)
Else
value.All(Function(e As ItemChoiceType)
Me.itemsElementNameField.Add(e)
End Function)
End If
End Set
End Property
```
Notice the use of linq to itterate through the passed collection and add to the existing collection and when the Get is called on the property, the collections .ToArray event passes back the array
You will need the use of following libraries, which you should already have if you are running into this problem
System.Core.System.Linq
System.Collections.Generic