2016-03-29 9 views
0

Ich versuche, eine ziemlich verschachtelte XML-Struktur in ein Objekt zu deserialisieren.XML Deserializer geht nicht tief genug in verschachtelte Tags

<engineLimits> 
     <engineName>BLAH</engineName> 
     <engineType>BLAH</engineType> 
     <engineSubtype>BLAH</engineSubtype> 
     <engineDirectory>blahh</engineDirectory> 
     <version>1.0</version> 
     <creationDate>blah</creationDate> 
     <testBed>blah</testBed> 

     <limit> 
      <!-- The title of the graph --> 
      <title>title</title> 

      <!-- Axis settings --> 
      <xAxis label="label" units="units" equation="equation" min="min" max="max" resolution="res"></xAxis> 
      <yAxis label="label" units="units" equation="equation" min="min" max="max" resolution="res"></yAxis> 

      <definition name="test">10</definition> 
      <averageLimit degree="3"> 
       <average color="grey"> 
        <points> 
         <point x="11" y="21"/> 
         <point x="12" y="22"/> 
         <point x="13" y="23"/> 
         <point x="14" y="24"/> 
         <point x="15" y="25"/> 
        </points> 
       </average> 
       <upperLimit color="red"> 
        <points> 
         <point y="12"/> 
         <point y="13"/> 
         <point y="14"/> 
         <point y="15"/> 
         <point y="16"/> 
        </points> 
       </upperLimit> 
       <lowerLimit color="red"> 
        <points> 
         <point y="12"/> 
         <point y="13"/> 
         <point y="14"/> 
         <point y="15"/> 
         <point y="16"/> 
        </points> 
       </lowerLimit> 
      </averageLimit> 
     </limit> 
</engineLimit> 

Hier ist ein Ausschnitt aus wie ich das Basisobjekt strukturiert:

<Serializable()> _ 
<XmlRoot("engineLimits")> _ 
Public Class EngineLimits 

    Dim myLimits As List(Of Limits.Limit) 

    Public Sub New() 
     myLimits = New List(Of Limits.Limit) 
    End Sub 

    <XmlElement("limit")> _ 
    Public Property limits As List(Of Limits.Limit) 
     Get 
      Return myLimits 
     End Get 
     Set(value As List(Of Limits.Limit)) 
      myLimits = value 
     End Set 
    End Property 

End Class 

Die Grenzwertklasse:

<XmlRoot("limit")> _ 
     Public Class Limit 
      Dim myAverageLimit As Components.AverageLimit 
      Dim myLineLimits As List(Of Components.LineLimit) 
      Dim myLines As List(Of Components.Line) 

      Public Sub New() 
       myLineLimits = New List(Of Components.LineLimit) 
       myLines = New List(Of Components.Line) 
      End Sub 

      <XmlElement("averageLimit")> _ 
      Public Property averageLimit() As Components.AverageLimit 
       Get 
        Return myAverageLimit 
       End Get 
       Set(value As Components.AverageLimit) 
        myAverageLimit = value 
       End Set 
      End Property  
     End Class 

Die averageLimit Klasse:

<XmlRoot("averageLimit")> _ 
      Public Class AverageLimit 

       Dim myDegree As Integer 
       Dim myAverage As Average 
       Dim myUpperLimit As DerivedLimit 
       Dim myLowerLimit As DerivedLimit 

       Public Sub New() 
       End Sub 

       <XmlAttribute("degree")> _ 
       Public Property degree() As Integer 
        Get 
         Return myDegree 
        End Get 
        Set(value As Integer) 
         myDegree = value 
        End Set 
       End Property 

       <XmlElement("average")> _ 
       Public Property average() As Average 
        Get 
         Return myAverage 
        End Get 
        Set(value As Average) 
         myAverage = value 
        End Set 
       End Property 

Und schließlich die Durchschnittsklasse:

Mein Problem ist, dass die Deserialisierung nicht weit genug in die verschachtelten Tags geht. Wenn ich das Programm ausführe, wird alles bis auf die Punkte korrekt ausgefüllt. Für das Leben von mir, in der Klasse average, kann ich nicht die list(Of linePoints) zu analysieren! Hier

ist die linePoints Klasse:

<XmlRoot("point")> _ 
      Public Class LinePoint 

       Dim myX As Double 
       Dim myY As Double 

       Public Sub New() 
       End Sub 

       <XmlAttribute("x")> _ 
       Public Property x() As Double 
        Get 
         Return myX 
        End Get 
        Set(value As Double) 
         myX = value 
        End Set 
       End Property 

       <XmlAttribute("y")> _ 
       Public Property y() As Double 
        Get 
         Return myY 
        End Get 
        Set(value As Double) 
         myY = value 
        End Set 
       End Property 
      End Class 

FYI, degree korrekt analysiert wird. Ist es in Ordnung, eine <XmlArray> auf einer Eigenschaft zu definieren, die nicht wirklich eine array ist, sondern eine list?

EDIT

Das ist mein Deserialisierung Code:

Try 
       ' Create a new file stream for reading the XML file 
       Using fs = New StreamReader("C:\Users\u3201656\Desktop\test.xml") 
        ' Construct a XmlSerializer and use it 
        ' to serialize the data from the stream. 
        Dim SerializerObj = New XmlSerializer(GetType(EngineLimits)) 
        Try 
         ' Deserialize the hashtable from the file 
         engineLimits = DirectCast(SerializerObj.Deserialize(fs), EngineLimits) 
        Catch ex As Exception 
         Console.WriteLine(String.Format("Failed to serialize. Reason: {0}", ex.Message)) 
        End Try 
       End Using ' put a break point here and mouse-over engineLimits…. 

      Catch ex As Exception 
       Console.WriteLine(ex.Message) 
      End Try 
+0

Sie haben die Limit-Klasse nicht veröffentlicht - dies könnte Hinweise enthalten - entfernen Sie zur Verdeutlichung auch alle Bits, die nicht relevant sind. –

+0

Ich habe die Frage geändert, können Sie noch einen Blick darauf werfen? –

+0

@Matthew Goulart es ist normale Praxis auf SO, den ursprünglichen Autor des Codes, den Sie verwenden, zu kreditieren. – Monty

Antwort

1

A serializable Eigenschaft sollte immer einen öffentlichen Getter und Setter haben. Ihre Punkte Eigenschaft fehlt ein Getter:

<XmlArray("points")> _ 
<XmlArrayItem("point")> _ 
Public Property setPoints() As List(Of LinePoint) 
    Set(value As List(Of LinePoint)) 
     myPoints = value 
    End Set 
    Get 
     Return myPoints 
    End Get 
End Property 

Getestet Ihren obigen Code verwenden und alle Punkte in der XML in der Liste zu erhalten.

auch wenn Sie vs 2015 haben, können Sie Ihre Klassen ziemlich vereinfachen. Siehe unten. (Namespaces wurden entfernt, da ich diese nicht deklariert habe)

+0

Das war eine wirklich gute Antwort, besonders schätze ich die Klassenoptimierung. Ich habe in VS2013, scheint gut zu funktionieren. Danke noch einmal! –

+0

Kein Problem. Das Refactoring war einfach - ich benutze Nachschärfer - überprüfen Sie es, wenn Sie nicht damit vertraut sind. Ich habe diese Klassenänderungen mit ein paar Klicks erstellt. –