locked
Generating Xml Elements With Derived Class Names Instead of Type Attributes RRS feed

  • Question

  • I have the following classes which I want to serialize:
    <XmlInclude(GetType(MyType1)), XmlInclude(GetType(MyType2)), XmlInclude(GetType(MyType3))> Public MustInherit Class MyBaseType
    End Class
    
    Public Class MyType1 : Inherits MyBaseType
    End Class
    
    Public Class MyType2 : Inherits MyBaseType
    End Class
    
    Public Class MyType3 : Inherits MyBaseType
    End Class

    What I am actually serializing is a variable of type List(Of MyBaseType), and the generated Xml contains elements that look like the following:
    <MyBaseType xsi:type="MyType1">
    </MyBaseType>
    <MyBaseType xsi:type="MyType2">
    </MyBaseType>
    <MyBaseType xsi:type="MyType3">
    </MyBaseType>

    This works to provide the functionality, but I would like to know if there is a way to have it generate Xml that contains elements with the actual names of the derived classes, like the following:
    <MyType1>
    </MyType1>
    <MyType2>
    </MyType2>
    <MyType3>
    </MyType3>

    Is there a way to do this? It would make it much easier when the Xml needs edited manually or when creating external apps that need to read the Xml. Any help would be appreciated. Thanks.

    Nathan Sokalski njsokalski@hotmail.com http://www.nathansokalski.com/

    Sunday, August 11, 2013 3:21 AM

Answers

  • Hi,Nathan

    There are some code below may can  help you:

    I create two class objects which inherit from class Employee:

    Public Class Group
            <XmlArrayItem(GetType(Employee)), XmlArrayItem(GetType(Manager)), XmlArrayItem(GetType(Worker))> _
    	Public Property MyData() As List(Of Employee)
    		Get
    			Return m_MyData
    		End Get
    		Set
    			m_MyData = Value
    		End Set
    	End Property
    	Private m_MyData As List(Of Employee)
    
    End Class
    
    Public Class Employee
    	Public Name As String
    End Class
    
    Public Class Manager:Inherits Employee
    	Public Level As Integer
    End Class
    
    Public Class Worker:Inherits Employee
    	Public labor As Integer
    End Class

    Then you can create a method to Serialize objects to Xml Elements,code like this:

    Public Sub SerializeObject()
    Dim mydata As New List(Of Employee)()
    mydata.Add(New Employee() With { _
    Key .Name = "jjjj" _
    })
    mydata.Add(New Manager() With { _
    Key .Level = 30 _
    })
    mydata.Add(New Worker() With { _
    Key .labor = 50 _
    })
    Dim model = New Group() With { _
    Key .MyData = mydata _
    }
    Dim serializer = New XmlSerializer(model.[GetType]())
    Try
    Dim applicationData = Windows.Storage.ApplicationData.Current
    Dim storageFolder = applicationData.LocalFolder
    Dim file = Await storageFolder.CreateFileAsync("FileName.xml", CreationCollisionOption.ReplaceExisting)
    Dim dataContractSerializer = New XmlSerializer(model.[GetType]())
    Dim memoryStream = New MemoryStream()
    dataContractSerializer.Serialize(memoryStream, model)
    memoryStream.Seek(0, SeekOrigin.Begin)
    Dim serialized As String = New StreamReader(memoryStream).ReadToEnd()
    memoryStream.Dispose()
    Dim doc = New XmlDocument()
    doc.LoadXml(serialized)
    Await doc.SaveToFileAsync(file)
    Catch exception As Exception
    End Try

    End Sub

    Best Wishes!


    • Edited by Anne Jing Monday, August 12, 2013 4:20 PM from
    • Marked as answer by Anne Jing Friday, August 16, 2013 2:15 PM
    Monday, August 12, 2013 4:16 PM

All replies

  • Hi,Nathan

    There are some code below may can  help you:

    I create two class objects which inherit from class Employee:

    Public Class Group
            <XmlArrayItem(GetType(Employee)), XmlArrayItem(GetType(Manager)), XmlArrayItem(GetType(Worker))> _
    	Public Property MyData() As List(Of Employee)
    		Get
    			Return m_MyData
    		End Get
    		Set
    			m_MyData = Value
    		End Set
    	End Property
    	Private m_MyData As List(Of Employee)
    
    End Class
    
    Public Class Employee
    	Public Name As String
    End Class
    
    Public Class Manager:Inherits Employee
    	Public Level As Integer
    End Class
    
    Public Class Worker:Inherits Employee
    	Public labor As Integer
    End Class

    Then you can create a method to Serialize objects to Xml Elements,code like this:

    Public Sub SerializeObject()
    Dim mydata As New List(Of Employee)()
    mydata.Add(New Employee() With { _
    Key .Name = "jjjj" _
    })
    mydata.Add(New Manager() With { _
    Key .Level = 30 _
    })
    mydata.Add(New Worker() With { _
    Key .labor = 50 _
    })
    Dim model = New Group() With { _
    Key .MyData = mydata _
    }
    Dim serializer = New XmlSerializer(model.[GetType]())
    Try
    Dim applicationData = Windows.Storage.ApplicationData.Current
    Dim storageFolder = applicationData.LocalFolder
    Dim file = Await storageFolder.CreateFileAsync("FileName.xml", CreationCollisionOption.ReplaceExisting)
    Dim dataContractSerializer = New XmlSerializer(model.[GetType]())
    Dim memoryStream = New MemoryStream()
    dataContractSerializer.Serialize(memoryStream, model)
    memoryStream.Seek(0, SeekOrigin.Begin)
    Dim serialized As String = New StreamReader(memoryStream).ReadToEnd()
    memoryStream.Dispose()
    Dim doc = New XmlDocument()
    doc.LoadXml(serialized)
    Await doc.SaveToFileAsync(file)
    Catch exception As Exception
    End Try

    End Sub

    Best Wishes!


    • Edited by Anne Jing Monday, August 12, 2013 4:20 PM from
    • Marked as answer by Anne Jing Friday, August 16, 2013 2:15 PM
    Monday, August 12, 2013 4:16 PM
  • There is one important difference between your code and mine. Your List is a property of a Class, my list is a variable. I am not serializing a class, I am serializing a List. Is there a way to apply your technique to my scenario without creating an extra class? Thanks.

    Nathan Sokalski njsokalski@hotmail.com http://www.nathansokalski.com/

    Monday, August 12, 2013 8:07 PM
  • Hi,Nathan

    I think usually the  XmlArrayItemAttribute class be used to control the XmlSerializer serializes or deserializes an object.But you  can only apply the XmlArrayAttribute to a public field or read/write property  in a class.So you do not directly use it in a variable.

    You can refer to this link:

    http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlarrayitemattribute.aspx

    Else,you can customize the serialization style:

    Refer to this link:

    http://msdn.microsoft.com/en-us/library/system.xml.xmlelement.aspx


    • Edited by Anne Jing Thursday, August 15, 2013 2:44 AM from
    Tuesday, August 13, 2013 2:45 PM