序列化包含另一个 keyedcollection 的 Keyedcollection

Serialize Keyedcollection which contains another keyedcollection

我最近开始与来自 vba 的 vb.net 合作。

对于我计划的应用程序,我想创建一个 KeyedCollection 来存储另一个 keyedcollection。原因是我有一种数据库,我希望能够在其中存储不同数量的 "Parametersets",现在未定义数量的 "List_of_Parameters",其中存储系数数组。 我的问题在于序列化。 当我 运行 XMLSerialization 时,只有嵌套最深的元素才能正确存储。上一层的元素仅称为 "Array_of_node",除了 keyedcollection 之外的所有变量都被忽略。

我原以为我会看到 class 名字。此外,我还以为会看到这样的东西。

<Database>
   <Species>
     <Name>Parameterset 1</Name>
     <Node>...</Node>
     <Node>...</Node>
   </Species>

...

任何帮助将不胜感激, 最好的祝福, 约翰内斯

这是我得到的 xml- 输出:

<?xml version="1.0" encoding="utf-8"?>
<Database xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <ArrayOfNode>
    <Node>
      <Name>ListOfParameters_1</Name>
      <value>
        <double>1</double>
        <double>2</double>
        <double>3</double>
      </value>
    </Node>
    <Node>
      <Name>ListOfParameters_2</Name>
      <value>
        <double>5</double>
        <double>6</double>
      </value>
    </Node>
  </ArrayOfNode>
  <ArrayOfNode>
    <Node>
      <Name>ListOfParameters_1</Name>
      <value>
        <double>7</double>
        <double>8</double>
        <double>9</double>
      </value>
    </Node>
    <Node>
      <Name>ListOfParameters_2</Name>
      <value>
        <double>10</double>
        <double>11</double>
      </value>
    </Node>
  </ArrayOfNode>
</Database>

这是我的数据库:

Imports System.Collections.ObjectModel
Imports TestListofList
Imports System.Xml.Serialization
Imports System.IO

<Serializable>
<XmlRootAttribute("Database")>
Public Class Database
    Inherits KeyedCollection(Of String, Species)

    Private myName As String
    Public Property Name() As String
        Get
            Return myName
        End Get
        Set(ByVal value As String)
            myName = value
        End Set
    End Property

    Protected Overrides Function GetKeyForItem(item As Species) As String
        Return item.Name
    End Function

    Sub New()
        MyBase.New()
    End Sub

    Sub New(ByVal name As String)
        Me.New()
        myName = name
    End Sub

    Public Sub SerializeToXML(ByVal filename As String)
        Dim locXMLWriter As New XmlSerializer(GetType(Database))
        Dim locXMLFile As New StreamWriter(filename)
        locXMLWriter.Serialize(locXMLFile, Me)
        locXMLFile.Flush()
        locXMLFile.Close()
    End Sub
End Class

这是 class 存储不同参数集的 "List_of_Coeffiencts" 列表:

Imports System.Collections.ObjectModel
Imports TestListofList
Imports System.Xml.Serialization

<Serializable>
Public Class Species
    Inherits KeyedCollection(Of String, Node)

    Public myName As String


    Public Property Name() As String
        Get
            Return myName
        End Get
        Set(ByVal value As String)
            myName = value
        End Set
    End Property

    Protected Overrides Function GetKeyForItem(item As Node) As String
        Return item.Name
    End Function

    Sub New()
        MyBase.New()
    End Sub
    Sub New(ByVal Name As String)
        Me.New()
        myName = Name
    End Sub
End Class

这是最后的 "List of coefficients"

Public Class Node
    Private myName As String
    Private myvalue As Double()
    Public Property Name() As String
        Get
            Return myName
        End Get
        Set(ByVal value As String)
            myName = value
        End Set
    End Property

    Public Property value() As Double()
        Get
            Return myvalue
        End Get
        Set(ByVal value As Double())
            myvalue = value
        End Set
    End Property

    Sub New()

    End Sub

    Sub New(ByVal Name As String, value() As Double)
        myName = Name
        myvalue = value
    End Sub
End Class

这是我的示例主程序:

Module Module1

    Sub Main()
        Dim dot As Node
        Dim molecule As Species
        Dim data As New Database

        molecule = New Species("Parameterset1")

        data.Add(molecule)
        dot = New Node("ListOfParameters_1", New Double() {1, 2, 3})
        data.Item("Parameterset1").Add(dot)
        dot = New Node("ListOfParameters_2", New Double() {5, 6})
        data.Item("Parameterset1").Add(dot)

        molecule = New Species("Parameterset2")
        data.Add(molecule)
        dot = New Node("ListOfParameters_1", New Double() {7, 8, 9})
        data.Item("Parameterset2").Add(dot)
        dot = New Node("ListOfParameters_2", New Double() {10, 11})
        data.Item("Parameterset2").Add(dot)




        data.SerializeToXML("C:\test.xml")
    End Sub

End Module

试试这个....(新代码和 类)

Imports System.IO
Imports System.Xml.Serialization

Module Module1

Sub Main()
    Dim Database1 As New List(Of Species)

    Dim Species1 As New Species
    Species1.Name = "SpeciesName1"
    Dim Parameterset1 As New Parameterset
    Parameterset1.Name = "Parameterset1"
    Parameterset1.Node.Add("1")
    Parameterset1.Node.Add("2")
    Parameterset1.Node.Add("3")
    Species1.Parameterset.Add(Parameterset1)

    Database1.Add(Species1)

    Dim Species2 As New Species
    Species2.Name = "SpeciesName2"
    Dim Parameterset2 As New Parameterset
    Parameterset2.Name = "Parameterset1"
    Parameterset2.Node.Add("1")
    Parameterset2.Node.Add("2")
    Species2.Parameterset.Add(Parameterset2)

    Database1.Add(Species2)

    ' to Serialize the object to test.xml
    Serialize(Database1)

    ' and to Deserialize from test.xml
    Dim Database2 As New List(Of Species)(Deserialize())
End Sub

Private Sub Serialize(SpeciesList As List(Of Species))

    ' Use a file stream here. 
    Using fs As New StreamWriter("test.xml")
        ' Construct a XmlSerializer and use it  
        ' to serialize the data to the stream. 
        Dim SerializerObj As New XmlSerializer(GetType(List(Of Species)))

        Try
            ' Serialize EmployeeList to the file stream
            SerializerObj.Serialize(fs, SpeciesList)
        Catch ex As Exception
            Console.WriteLine(String.Format("Failed to serialize. Reason: {0}", ex.Message))
        End Try
    End Using
End Sub

Private Function Deserialize() As List(Of Species)
    Dim EmployeeList2 = New List(Of Species)()

    ' Create a new file stream for reading the XML file
    Using fs = New StreamReader("test.xml")
        ' Construct a XmlSerializer and use it  
        ' to serialize the data from the stream. 
        Dim SerializerObj = New XmlSerializer(GetType(List(Of Species)))

        Try
            ' Deserialize the hashtable from the file
            EmployeeList2 = DirectCast(SerializerObj.Deserialize(fs), List(Of Species))
        Catch ex As Exception
            Console.WriteLine(String.Format("Failed to serialize. Reason: {0}", ex.Message))
        End Try
    End Using
    ' return the Deserialized data.
    Return EmployeeList2
End Function

End Module

<XmlRoot(ElementName:="Parameterset")>
Public Class Parameterset
    <XmlElement(ElementName:="Name")>
    Public Property Name As String

    <XmlElement(ElementName:="Node")>
    Public Property Node As List(Of String) = New List(Of String)
End Class

<XmlRoot(ElementName:="Species")>
Public Class Species

    <XmlElement(ElementName:="Name")>
    Public Property Name As String

    <XmlElement(ElementName:="Parameterset")>
    Public Property Parameterset As List(Of Parameterset) = New List(Of Parameterset)
End Class

<XmlRoot(ElementName:="Database")>
Public Class Database

    <XmlElement(ElementName:="Species")>
    Public Property Species As List(Of Species) = New List(Of Species)
End Class

XML 现在应该是这样的.....

    <?xml version="1.0" encoding="utf-8"?>
    <ArrayOfSpecies xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
      <Species>
        <Name>SpeciesName1</Name>
        <Parameterset>
          <Name>Parameterset1</Name>
          <Node>1</Node>
          <Node>2</Node>
          <Node>3</Node>
        </Parameterset>
      </Species>
      <Species>
        <Name>SpeciesName2</Name>
        <Parameterset>
          <Name>Parameterset1</Name>
          <Node>1</Node>
          <Node>2</Node>
        </Parameterset>
      </Species>
    </ArrayOfSpecies>