SteMMo SteMMo - 3 months ago 24 Question

Deserializing an element with different xsi:style

I need to deserialize a XML file that contains an element with two different types.


<loop xsi:type="loopDynamicLengthType">
<loop xsi:type="loopTerminatedType">

In my source the class is defined as:

<XmlElement("loop")> Public prLoop() As PosResponseLoop

The second one is defined as:

<XmlInclude(GetType(loopTerminatedType))> _
Public Class PosResponseLoop

The first one could be defined in a similar way and the same name,

<XmlInclude(GetType(loopDynamicLengthType))> _
Public Class PosResponseLoop

but the compiler says:

class 'PosResponseLoop' and class 'PosResponseLoop' conflict in namespace 'WindowsApplication1'.

How can i solve it?

dbc dbc

The standard attribute xsi:type allows an XML element to explicitly assert its type. In this case, the element <loop> can have two types, loopDynamicLengthType and loopTerminatedType. As explained here, XmlSerializer uses the xsi:type information to map the XML element to a specific .Net type. Thus what you need to do is have a single base class (possibly though not necessarily abstract) to represent any possible type of loop, with two subclasses, each corresponding to the two possible xsi:type values:

<XmlInclude(GetType(LoopTerminatedType))> _
<XmlInclude(GetType(LoopDynamicLengthType))> _
Public MustInherit Class PosResponseLoop
End Class

<XmlType("loopTerminatedType")> _
Public Class LoopTerminatedType
    Inherits PosResponseLoop
End Class

<XmlType("loopDynamicLengthType")> _
Public Class LoopDynamicLengthType
    Inherits PosResponseLoop
End Class

The <XmlInclude> attributes on the base class specify the set of possible subtypes that might be encountered. The <XmlType(String)> attributes on the derived classes specify the name that will appear as the value of the corresponding xsi:type attribute.

Then your containing type should look like:

Public Class RootObject
    <XmlElement("loop")> Public prLoop() As PosResponseLoop 
End Class

Sample fiddle.