Vb.net 使用XmlReader并忽略节点顺序

Vb.net 使用XmlReader并忽略节点顺序,vb.net,serialization,xml-serialization,xmlreader,backwards-compatibility,Vb.net,Serialization,Xml Serialization,Xmlreader,Backwards Compatibility,我试图实现“IXmlSerializable”接口,并努力实现“ReadXml”。以下是我的序列化xml: <?xml version="1.0" encoding="utf-16"?> <MyClass> <IntProperty>100</IntProperty> <BoolProperty>True</BoolProperty> <ArrayProperty> <ArrayEntr

我试图实现“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>

下面是一些解析地理编码数据的代码,它将帮助您完成大部分工作

对于“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
对于上面的代码,我只是将下面的代码用于“Address”类:


这是对我有用的。它在节点顺序方面是完全灵活的

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
Public子ReadXml(读卡器为System.Xml.XmlReader)实现IXmlSerializable.ReadXml
reader.MoveToContent()
虽然是真的
选择案例阅读器。名称
案例“IntProperty”
IntProperty=CInt(reader.ReadString())
案例“BoolProperty”
BoolProperty=CBool(reader.ReadString())
案例“StringProperty”
StringProperty=reader.ReadString()
“ArrayProperty”案
Dim ArrayEntry作为新列表(ArrayEntry的)
如果不是reader.Isemptyelment,那么
而reader.Read()
如果reader.Name为“ArrayEntry”,则在
Dim ar作为新ArrayEntry
ar.MyAttr=reader.GetAttribute(“MyAttr”)
arrayEntries.Add(ar)
结束时
如果结束
ArrayProperty=arrayEntries.ToArray()
结束选择
如果不是reader.Read(),则在
结束时
端接头

谢谢!考虑到“ArrayProperty”节点可能出现在“MyClass”节点下的任何位置,您能否提供一个如何解析“ArrayProperty”节点的示例?鉴于您正在处理的XML结构,我们可能很难理解上面的代码。你可以调用Read .Read来获取一个案例中的下一个元素。我不确定是否必须像示例中它处理属性的地方那样退出。这就是为什么我问:-)
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
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