Home > Software engineering >  Trying to write a List object to XML (VB.net)
Trying to write a List object to XML (VB.net)

Time:11-15

I've had no trouble writing a non-List object to XML, it reads and writes as expected. But making a List object write to XML is throwing my entire export/import process against the wall, and I can't figure out why.

Object is built off of this class:

    Public Class PowerArray
    'Array that stores Powers for active character
    Public Name As String
    Public PRating As Integer
    Public Action As String
    Public Cost As Integer
    Public PoolNone As String
    Public Pool1 As String
    Public Pool2 As String
    Public Range As String
    Public Duration As String
    Public Tags As New List(Of Object)
    Public Desc As String
End Class

Object created from the Class is:

Public Shared Property CharPowers As New List(Of PowerArray)

As an example, I can write the Object "CharCore" (as defined off of class "Character", and which isn't a list) to XML just fine.

If I try to write CharPowers as a populated List to XML, it throws an error from this:

    Dim writer As New System.Xml.Serialization.XmlSerializer(GetType(frmMain.PowerArray))
    Dim file As New System.IO.StreamWriter("c:\temp\"   "PowerTest.PWR")
    writer.Serialize(file, frmMain.GVar.CharPowers)
    file.Close()

-with error "InvalidCastException: Unable to cast object of type 'System.Collections.Generic.List`1[NICO_SP_v2.frmMain PowerArray]' to type 'PowerArray'."

I'm not sure what makes a List different here. Any help would be appreciated.

CodePudding user response:

An Xml document must have a root element, i.e. cannot just have a bunch of elements at the top level. So instead make a class to hold the list of PowerArray

Make your classes like this

Imports System.IO
Imports System.Xml.Serialization
<XmlRoot>
Public Class PowerArrays
    <XmlElement("PowerArray")>
    Public Property List As List(Of PowerArray)
End Class

Public Class PowerArray ' unchanged
    'Array that stores Powers for active character
    Public Name As String
    Public PRating As Integer
    Public Action As String
    Public Cost As Integer
    Public PoolNone As String
    Public Pool1 As String
    Public Pool2 As String
    Public Range As String
    Public Duration As String
    Public Tags As New List(Of Object)
    Public Desc As String
End Class

And serialize the root instead

Dim powers = New PowerArrays() With {.List = frmMain.GVar.CharPowers.ToList()}
Dim serializer As New XmlSerializer(GetType(PowerArrays))
Using writer As New StreamWriter($"c:\temp\{PowerTest.PWR}")
    serializer.Serialize(writer, powers)
End Using

Your Xml should result in

<?xml version="1.0" encoding="utf-8"?>
<PowerArrays>
  <PowerArray>
    <Name>foo</Name>
    ...
  </PowerArray>
  <PowerArray>
    <Name>bar</Name>
    ...
  </PowerArray>
</PowerArrays>

Deserialize in reverse

Dim powers = New PowerArrays()
Dim serializer As New XmlSerializer(GetType(PowerArrays))
Using reader As New StreamReader($"c:\temp\{PowerTest.PWR}")
    powers = DirectCast(serializer.Deserialize(reader), PowerArrays)
End Using
  • Related