1

我正在嘗試實現'IXmlSerializable'接口並與'ReadXml'實現作鬥爭。這裏是我的序列化的XML:使用XmlReader並忽略節點的順序

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

回答

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

謝謝!你能否提供一個如何解析'ArrayProperty'節點的例子,記住它可能發生在'MyClass'節點下的任何地方? – jor

+0

鑑於您正在處理的XML結構,我們可能很難使用上面的代碼。您可以調用reader.read來獲取CASE中間的下一個元素。我不確定是否必須退出處理屬性的示例中顯示的內容。 – rheitzman

+0

這就是爲什麼我問:-) – jor