2016-03-29 11 views
0

かなりネストされたXML構造をオブジェクトにデシリアライズしようとしています。ここで XMLデシリアライザがネストされたタグに十分に深く入っていない

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

は、私はベースオブジェクトを構造化する方法の抜粋です:

<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 

制限クラス:

<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 

averageLimitクラス:

<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 

そして最後に平均クラス:

<XmlRoot("average")> _ 
     Public Class Average 

      Dim myPoints As List(Of LinePoint) 

      Public Sub New() 
       myPoints = New List(Of LinePoint) 
      End Sub 

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

私の問題は、デシリアライゼーションがネストされたタグに十分に届かないということです。私がプログラムを実行すると、ポイントを除いてすべてが正しく行の下に記入されます。私の人生のために、averageクラスでは、私はすることができますlist(Of linePoints)を解析する!ここで

がlinePointsクラスです:FYI

<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 

degreeが正しく解析されます。実際にはarrayではなくlistというプロパティに<XmlArray>を定義しても構いませんか?

EDIT

これは私のデシリアライゼーションコードです:

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

あなたはリミットクラスを投稿していない - これは、手がかりを保持することができる - また、明確にするためだけ関連していないすべてのビットを削除します。 –

+0

私は質問を変更しました。もう一度見てもらえますか? –

+0

@Matthew Goulartあなたが使っているコードの元の著者には、それを信用するのが普通です。 – Monty

答えて

1

シリアライズ可能なプロパティは、常に公共のgetterとsetterを持つべきです。あなたのポイントプロパティにはゲッターがありません:

<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 

上記のコードを使用してテストし、リスト内のxmlのすべてのポイントを取得してください。

vs 2015の場合でも、クラスをかなり単純化することができます。下記参照。 (私はそれらを宣言していなかったとして、名前空間が削除されている)

<Serializable()> _ 
<XmlRoot("engineLimits")> 
Public Class EngineLimits 
    <XmlElement("limit")> 
    Public Property Limits As List(Of Limit) = New List(Of Limit)() 
End Class 

<XmlRoot("limit")> 
Public Class Limit 
    <XmlElement("averageLimit")> 
    Public Property AverageLimit As AverageLimit 
End Class 

<XmlRoot("averageLimit")> 
Public Class AverageLimit 
    <XmlAttribute("degree")> 
    Public Property Degree As Integer 

    <XmlElement("average")> 
    Public Property Average As Average 
End Class 

<XmlRoot("average")> 
Public Class Average 
    <XmlArray("points")> _ 
    <XmlArrayItem("point")> 
    Public Property SetPoints As List(Of LinePoint) = New List(Of LinePoint) 
End Class 

<XmlRoot("point")> 
Public Class LinePoint 
    <XmlAttribute("x")> 
    Public Property X As Double 

    <XmlAttribute("y")> 
    Public Property Y As Double 
End Class 
+0

これは本当に良い答えでした。私は特にクラスの最適化に感謝します。私はVS2013で行った、うまくいくようだ。再度、感謝します! –

+0

問題ありません。リファクタリングは簡単でした - 私はresharperを使用しています - あなたがそれに精通していなければそれをチェックしてください。私は数回のクリックでこれらのクラスの変更を作成しました。 –

関連する問題