XML 反序列化器对嵌套标签的深入程度不够

XML Deserializer not going deep enough into nested tags

我正在尝试将相当嵌套的 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

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

平均限额class:

<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

最后是平均值 class:

<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 class 中,我无法解析 list(Of linePoints)

这里是线点 class:

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

编辑

这是我的反序列化代码:

   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

一个可序列化的 属性 应该总是有一个 public getter 和 setter。您的积分 属性 缺少 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

使用您上面的代码进行测试并获得列表中 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