2016-03-21 5 views
1

私は最近、vbaから来ているvb.netでの作業を開始しました。別のキー付きコレクションを含むSerialed Keyedcollection

私の計画しているアプリケーションでは、別のkeyedcollectionを格納するKeyedCollectionを作成したかったのです。なぜなら、私はさまざまな数の "Parametersets"を格納できるようにするデータベースの種類があるからです。ここでは、係数の配列が格納される "List_of_Parameters"の未定義数です。 私の問題はシリアル化にあります。 XMLSerializationを実行すると、最も深くネストされた要素のみが正しく格納されます。 1レベル上の要素は単に "Array_of_node"と呼ばれ、keyedcollection以外のすべての変数は無視されます。

私は、クラス名が表示されるのではなく、予想通りでした。さらに、私はこのようなことを期待していました。

<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 

これは、異なるparametersetsのための "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 

これが最後の「係数リスト」

です
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 
+0

問題は、コレクションのプロパティをシリアル化しようとしていることです。 'XmlSerializer'はこれをサポートしていません。 [ICollectionインターフェイスを実装するクラスのシリアライズ](https://msdn.microsoft.com/en-us/library/58a18dwa%28v=vs.110%29.aspx)**任意のパブリックプロパティまたはフィールドを追加クラスはシリアライズされません。 [IList を実装すると、[方法/ XmlSerializerでクラスを別の方法で扱うのはなぜですか?](https://stackoverflow.com/questions/31552724) – dbc

+0

関連項目[List <>からクラスが継承される場合、XmlSerializerはシリアル化されません他の属性](https://stackoverflow.com/questions/5069099/when-a-class-is-inherited-from-list-xmlserializer-doesnt-serialize-other-att)。回避策については、[ICollection をXMLに読み書きするプロパティをシリアル化する方法](https://stackoverflow.com/questions/34221481/how-to-serialize-an-icollectiont-that-also)を参照してください。 -has-read-write-properties-to-xml) – dbc

+0

あなたの努力と説明をありがとう。私はそれを知らなかった。私はあなたのリンクの1つで言及されたdatacontractserializerを試し、私の問題に合った結果を得ることができるのを見ます。もしそうなら、私は投稿します。 – Johannes

答えて

1

(新コードおよびクラス)....これを試してみてください

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> 
+0

ありがとうございます。 – Johannes

+0

データ構造をこのようなものに変更することは可能だと思いますか? – Johannes

+0

<種の配列> SpeciesName Parameterset1ノード1ノード2 .... Johannes

関連する問題