我正在尝试实现'IXmlSerializable'接口并努力实现'ReadXml'。这是我的序列化xml:
<?xml version="1.0" encoding="utf-16"?>
<MyClass>
<IntProperty>100</IntProperty>
<BoolProperty>True</BoolProperty>
<ArrayProperty>
<ArrayEntry MyAttr="Bob" />
<ArrayEntry MyAttr="Alice" />
</ArrayProperty>
<StringProperty>Hello World!</StringProperty>
</MyClass>
有一个“小”特殊要求,反序列化必须向后兼容到可能具有不同元素顺序的旧序列化版本,缺少元素或者有其他(现在未使用过的)元素。我怎么能这样做?
Public Class MyClass
Implements IXmlSerializable
Public Property IntProperty As Integer
Public Property BoolProperty As Boolean
Public Property ArrayProperty As ArrayEntry()
Public Property StringProperty As String
Public Sub ReadXml(reader As System.Xml.XmlReader) Implements IXmlSerializable.ReadXml
' to be done ...
End Sub
' ...
End Class
Public Class ArrayEntry
Public Property MyAttr As String
End Class
答案 0 :(得分:2)
这对我有用。它在节点顺序方面完全灵活。
Public Sub ReadXml(reader As System.Xml.XmlReader) Implements IXmlSerializable.ReadXml
reader.MoveToContent()
While True
Select Case reader.Name
Case "IntProperty"
IntProperty = CInt(reader.ReadString())
Case "BoolProperty"
BoolProperty = CBool(reader.ReadString())
Case "StringProperty"
StringProperty = reader.ReadString()
Case "ArrayProperty"
Dim arrayEntries As New List(Of ArrayEntry)
If Not reader.IsEmptyElement Then
While reader.Read()
If reader.Name <> "ArrayEntry" Then Exit While
Dim ar As New ArrayEntry
ar.MyAttr = reader.GetAttribute("MyAttr")
arrayEntries.Add(ar)
End While
End If
ArrayProperty = arrayEntries.ToArray()
End Select
If Not reader.Read() Then Exit While
End While
End Sub
答案 1 :(得分:0)
以下是一些用于解析地理编码数据的代码,这些代码可以帮助您完成大部分工作。
在你的Case'ArrayProperty'中你需要使用Reader.Read来嵌套元素。
URL = "http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20geo.placefinder%20where%20text%3D%22{0}%22&diagnostics=true"
URL = String.Format(URL, sLocation)
Try
reader = New XmlTextReader(URL)
'reader.WhitespaceHandling = WhitespaceHandling.None 'Disable whitespace so that you don't have to read over whitespaces
With Address
While (reader.Read())
Debug.Print(reader.Name.ToString())
Select Case reader.Name.ToString()
Case "Result"
If reader.HasAttributes Then
For i = 0 To CShort(reader.AttributeCount - 1)
reader.MoveToAttribute(i)
Select Case reader.Name.ToString
Case "precision"
.precision = reader.GetAttribute(reader.Name.ToString)
Case "warning"
.warning = reader.GetAttribute(reader.Name.ToString)
bOK = False
End Select
reader.MoveToElement() ' Move the reader back to the element node.
Next
End If
Case "ErrorMessage"
.warning = reader.ReadString().ToString()
Case "quality"
.precision = reader.ReadString().ToString()
Case "line1"
.Street = reader.ReadString().ToString()
Case "city"
.City = reader.ReadString().ToString()
Case "statecode"
.State = reader.ReadString().ToString()
Case "postal"
.Zip = reader.ReadString().ToString()
Case "country"
.Country = reader.ReadString().ToString()
Case "offsetlat"
.Latitude = reader.ReadString().ToString()
Case "offsetlon"
.Longitude = reader.ReadString().ToString()
End Select
End While
End With
Catch ex As Exception
bOK = False
Address.warning = ex.Message
End Try
对于上面的代码,我只使用下面的代码作为“地址”类:
Private Structure Address_struct
Public Street As String
Public City As String
Public State As String
Public Zip As String
Public Country As String
Public Latitude As String
Public Longitude As String
Public precision As String
Public warning As String
End Structure
Dim Address As Address_struct