Search code examples
xmlvb.netxml-deserialization

Deserialize XML array in vb.net


I need to deserialize a XML file in VB.NET.

I'm using the standard XML library. I'm not able to write down the vb code to define the following structure:

<myvar>
    <var>...</var>
    <troublecodes>
        <troublecode>
        ...
        </troublecode>
        <troublecode>
        ....
        </troublecode>
        <statusbyte>
        ....
        </statusbyte>
        <statusbyte>
        ....
        </statusbyte>
        <statusbyte>
        ....
        </statusbyte>
    </troublecodes>
</myvar>

My definitions are:

Public Class MyVar
  <XmlElement("var")> Public name As String
  <XmlElement("troublecodes")> Public troubleCodes As TroubleCodes
End Class

Public Class TroubleCodes
<XmlArrayItem("troublecode")> Public troubleCode() As TroubleCode
<XmlArrayItem("statusbyte")> Public statusByte() As StatusByte
End Class

Public Class TroubleCode
  <XmlElement("one")> Public one As String
  <XmlElement("two")> Public two As String
End Class

Public Class StatusByte
  <XmlElement("three")> Public threeAs String
  <XmlElement("four")> Public four As String
End Class

but the objects are not populated by the deserialization.
How can i define them?


Solution

  • Problems in deserialization can typically be diagnosed by serializing an example of your root type and comparing the generated XML with the desired XML. If I do so with your MyVar type (demo fiddle) I get the following result:

    <MyVar>
      <var>my name</var>
      <troublecodes>
        <troubleCode>
          <troublecode>
            <one>one</one>
            <two>two</two>
          </troublecode>
        </troubleCode>
        <statusByte>
          <statusbyte>
            <three>three</three>
            <four>four</four>
          </statusbyte>
        </statusByte>
      </troublecodes>
    </MyVar>
    

    This has the following problems:

    • The root node is incorrectly capitalized.

      This can be fixed by adding <XmlRoot("myvar")> to your root type.

    • There is an extra level of nesting of <troubleCode>.

      By default, XmlSerializer serializes all collections including arrays with an outer container element. To suppress the outer container element and serialize the collection as a flat sequence of elements, replace the XmlArrayItem attribute with <XmlElement("troublecode")>.

    • There is also an extra level of nesting of <statusByte>.

    Thus your types should be as follows:

    <XmlRoot("myvar")> _
    Public Class MyVar
        <XmlElement("var")> Public name As String
        <XmlElement("troublecodes")> Public troubleCodes As TroubleCodes
    End Class
    
    Public Class TroubleCodes
        <XmlElement("troublecode")> Public troubleCode() As TroubleCode
        <XmlElement("statusbyte")> Public statusByte() As StatusByte
    End Class
    
    Public Class TroubleCode
        <XmlElement("one")> Public one As String
        <XmlElement("two")> Public two As String
    End Class
    
    Public Class StatusByte
        <XmlElement("three")> Public three As String
        <XmlElement("four")> Public four As String
    End Class
    

    Fixed fiddle.