Results 1 to 1 of 1

Thread: Problems with complex XML serialization

Threaded View

  1. #1

    Thread Starter
    PowerPoster formlesstree4's Avatar
    Join Date
    Jun 2008
    Posts
    3,250

    Problems with complex XML serialization

    I've got a class that has variables referencing to other sub classes:

    Code:
    Public Class BasePokemon
        
        'Private Variables
        <XmlAttribute("Name")> _
        Public _name As String = String.Empty
    
        <XmlAttribute("Type 1")> _
        Public _type1 As PokemonType = PokemonType.Blank
    
        <XmlAttribute("Type 2")> _
        Public _type2 As PokemonType = PokemonType.Blank
    
        <XmlAttribute("EggGroup")> _
        Public _egg As EggGroup = EggGroup.Blank
    
        <XmlAttribute("basestats", GetType(BaseStats))> _
        Public _stats As New BaseStats
    
        <XmlAttribute("capabilities", GetType(Capabilities))> _
        Public _capabilities As New Capabilities
    
        ''' <summary>
        ''' Saves the current data.
        ''' </summary>
        ''' <param name="xmlpath">The location of the XML file.</param>
        ''' <remarks></remarks>
        Public Sub Save(ByVal xmlpath As String)
    
            'Create the saver.
            Dim Saver As New XmlSerializer(GetType(BasePokemon))
    
            'Create the filestream.
            Dim Stream As New FileStream(xmlpath, FileMode.Create)
    
            'Save the data
            Saver.Serialize(Stream, Me) 'Error right here.
    
            'Close the stream
            Stream.Close()
    
        End Sub
    
        ''' <summary>
        ''' Loads a XML file to be parsed.
        ''' </summary>
        ''' <param name="xmlpath"></param>
        ''' <remarks></remarks>
        Public Sub Load(ByVal xmlpath As String)
    
            'Create the Loader.
            Dim Loader As New XmlSerializer(GetType(BasePokemon))
    
            'Check for the file.
            If File.Exists(xmlpath) Then
    
                'Load it.
                Dim Stream As New FileStream(xmlpath, FileMode.Open)
    
                'Deserialize it.
                Dim BasePoke As BasePokemon = CType(Loader.Deserialize(Stream), BasePokemon)
    
    
            End If
    
        End Sub
    
    End Class
    
    <XmlInclude(GetType(BasePokemon))> _
    Public Class BaseStats
        Public Property HP As Integer = 0I
        Public Property Atk As Integer = 0I
        Public Property Def As Integer = 0I
        Public Property SpAtk As Integer = 0I
        Public Property SpDef As Integer = 0I
        Public Property Spd As Integer = 0I
    End Class
    
    <XmlInclude(GetType(BasePokemon))> _
    Public Class Capabilities
        Public Property Overland As Integer = 0I
        Public Property Surface As Integer = 0I
        Public Property Underwater As Integer = 0I
        Public Property Sky As Integer = 0I
        Public Property Burrow As Integer = 0I
        Public Property Jump As Integer = 0I
        Public Property Power As Integer = 0I
        Public Property Intelligence As Integer = 0I
        Public Property CustomCapabilities As New List(Of String)
    End Class
    Whenever I try serializing the data, no matter what I do, I get this exception:

    Code:
    System.InvalidOperationException was unhandled
      Message=There was an error reflecting type 'TableTopManager.BasePokemon'.
      Source=System.Xml
      StackTrace:
           at System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel model, String ns, ImportContext context, String dataType, XmlAttributes a, Boolean repeats, Boolean openModel, RecursionLimiter limiter)
           at System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel model, String ns, ImportContext context, String dataType, XmlAttributes a, RecursionLimiter limiter)
           at System.Xml.Serialization.XmlReflectionImporter.ImportElement(TypeModel model, XmlRootAttribute root, String defaultNamespace, RecursionLimiter limiter)
           at System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(Type type, XmlRootAttribute root, String defaultNamespace)
           at System.Xml.Serialization.XmlSerializer..ctor(Type type, String defaultNamespace)
           at System.Xml.Serialization.XmlSerializer..ctor(Type type)
           at TableTopManager.BasePokemon.Save(String xmlpath) in e:\documents and settings\formlesstree4\my documents\visual studio 2010\Projects\TableTopManager\TableTopManager\Classes\PokemonSerializer.vb:line 34
           at TableTopManager.pokemon_form.Button1_Click(Object sender, EventArgs e) in e:\documents and settings\formlesstree4\my documents\visual studio 2010\Projects\TableTopManager\TableTopManager\Main Forms\pokemon_form.vb:line 5
           at System.Windows.Forms.Control.OnClick(EventArgs e)
           at System.Windows.Forms.Button.OnClick(EventArgs e)
           at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
           at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
           at System.Windows.Forms.Control.WndProc(Message& m)
           at System.Windows.Forms.ButtonBase.WndProc(Message& m)
           at System.Windows.Forms.Button.WndProc(Message& m)
           at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
           at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
           at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
           at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
           at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
           at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
           at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
           at System.Windows.Forms.Application.Run(ApplicationContext context)
           at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun()
           at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel()
           at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(String[] commandLine)
           at TableTopManager.My.MyApplication.Main(String[] Args) in 17d14f5c-a337-4978-8281-53493378c1071.vb:line 81
           at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
           at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
           at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
           at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
           at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
           at System.Threading.ThreadHelper.ThreadStart()
      InnerException: System.InvalidOperationException
           Message=There was an error reflecting field '_stats'.
           Source=System.Xml
           StackTrace:
                at System.Xml.Serialization.XmlReflectionImporter.InitializeStructMembers(StructMapping mapping, StructModel model, Boolean openModel, String typeName, RecursionLimiter limiter)
                at System.Xml.Serialization.XmlReflectionImporter.ImportStructLikeMapping(StructModel model, String ns, Boolean openModel, XmlAttributes a, RecursionLimiter limiter)
                at System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel model, String ns, ImportContext context, String dataType, XmlAttributes a, Boolean repeats, Boolean openModel, RecursionLimiter limiter)
           InnerException: System.InvalidOperationException
                Message=Cannot serialize member '_stats' of type TableTopManager.BaseStats. XmlAttribute/XmlText cannot be used to encode complex types.
                Source=System.Xml
                StackTrace:
                     at System.Xml.Serialization.XmlReflectionImporter.ImportAccessorMapping(MemberMapping accessor, FieldModel model, XmlAttributes a, String ns, Type choiceIdentifierType, Boolean rpc, Boolean openModel, RecursionLimiter limiter)
                     at System.Xml.Serialization.XmlReflectionImporter.ImportFieldMapping(StructModel parent, FieldModel model, XmlAttributes a, String ns, RecursionLimiter limiter)
                     at System.Xml.Serialization.XmlReflectionImporter.InitializeStructMembers(StructMapping mapping, StructModel model, Boolean openModel, String typeName, RecursionLimiter limiter)
                InnerException:
    Is there any way around this? I really would like to use an XmlSerializer to store this data rather than Binary Serialization. I've tried changing the GetType() of each of the variables to BasePokemon but it still throws the exception.


    EDIT: Doing some research indicates I might have to implement IXmlSerializable. I'm working on it now, but have no experience with this. Turning to google but would love some replies.

    EDIT 2: Well, was able to successfully implement writing...it writes. I can't assign an attribute name to it though which sucks. Still looking into more stuff.

    EDIT 3: You know what, I'm not gonna worry about applying XmlAttributes...it doesn't want to be nice to me. If I apply the XmlInclude Attribute, it serializes just fine. I'll leave this unresolved for now as I'd like to be able to find a way to apply XmlAttributes to complex types.
    Last edited by formlesstree4; Oct 4th, 2010 at 01:24 AM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width