XML反序列化器不能深入嵌套标记

时间:2016-03-29 15:08:00

标签: xml vb.net xml-serialization xmlserializer

我试图将一个相当嵌套的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类:

<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已正确解析。是否可以在实际上不是<XmlArray>而是array的属性上定义list

修改

这是我的反序列化代码:

   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

1 个答案:

答案 0 :(得分: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