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