简体   繁体   中英

trying to serialize and deserialize an complex xml file using VB.net

i am beginner in XML on visual studio 2015 (VB). The Deserialize will just work for valueA and valueB. But the accounts are empty. I dont understand this problem. what can i do? Or what is the right way for deserialize this XML-file and how can i access the var's in vb? Thanx!!!

I have follow XML file:

<?xml version="1.0" encoding="utf-16"?>
<clsSettings>
    <valueA>20</valueA>
    <valueB>5</valueB>
    <Accounts>
        <Account>
            <User>tralala</User>
            <Pw>tralala</Pw>
        </Account>
        <Account>
            <User>triliki</User>
            <Pw>trierer</Pw>
        </Account>
    </Accounts>
</clsSettings>

This is my Class:

Public Class clsSettings
    Public valueA As String
    Public valueB As String
    Public MyAccounts As Accounts
End Class

Public Class Accounts
    Public MyAccount As List(Of Account)
End Class

Public Class Account
    Public User As String
    Public Pw As String
End Class

And her is the code:

    Dim objSerializer As XmlSerializer
        Dim objStream As System.IO.FileStream

        If My.Computer.FileSystem.FileExists("settings.xml") Then
            objStream = New System.IO.FileStream("settings.xml", IO.FileMode.Open)
            objSerializer = New XmlSerializer(GetType(clsSettings))
            Try
                Settings = CType(objSerializer.Deserialize(objStream), clsSettings)
                readSettings()
            Catch ex As InvalidOperationException
                SetText(txt_status, "XML ERROR " + ex.Message)

            Catch ex As SerializationException
                SetText(txt_status, "XML ERROR " + ex.Message)

            Catch ex As IOException
                SetText(txt_status, "XML IO ERROR " + ex.Message)

            Finally
                objStream.Close()
            End Try
end if

You can get Visual Studio to create classes for your XML if you have it in the paste buffer and choose "Edit" -> "Paste Special" -> "Paste XML As Classes". I did that in a new class file and got

'''<remarks/>
<System.Xml.Serialization.XmlTypeAttribute(AnonymousType:=True),
System.Xml.Serialization.XmlRootAttribute([Namespace]:="", IsNullable:=False)>
Partial Public Class clsSettings

    Private valueAField As Byte

    Private valueBField As Byte

    Private accountsField() As clsSettingsAccount

    '''<remarks/>
    Public Property valueA() As Byte
        Get
            Return Me.valueAField
        End Get
        Set
            Me.valueAField = Value
        End Set
    End Property

    '''<remarks/>
    Public Property valueB() As Byte
        Get
            Return Me.valueBField
        End Get
        Set
            Me.valueBField = Value
        End Set
    End Property

    '''<remarks/>
    <System.Xml.Serialization.XmlArrayItemAttribute("Account", IsNullable:=False)>
    Public Property Accounts() As clsSettingsAccount()
        Get
            Return Me.accountsField
        End Get
        Set
            Me.accountsField = Value
        End Set
    End Property
End Class

'''<remarks/>
<System.Xml.Serialization.XmlTypeAttribute(AnonymousType:=True)>
Partial Public Class clsSettingsAccount

    Private userField As String

    Private pwField As String

    '''<remarks/>
    Public Property User() As String
        Get
            Return Me.userField
        End Get
        Set
            Me.userField = Value
        End Set
    End Property

    '''<remarks/>
    Public Property Pw() As String
        Get
            Return Me.pwField
        End Get
        Set
            Me.pwField = Value
        End Set
    End Property
End Class

Note that it uses the minimal-sized data types to store what it saw in the paste, so things like "ValueA" have been set to be of type Byte . You probably want to change those.

Next, I noticed that your XML declaration included "encoding="utf-16"", so I carefully saved your example data with that encoding (using little-endian and including the BOM). I had tried without doing that and I got an error "There is an error in XML document(0,0)".

With all that set up, I used a simple console application:

Imports System.Xml.Serialization

Module Module1


    Sub X(src As String)
        Dim objSerializer As XmlSerializer

        Dim settings As New clsSettings

        If My.Computer.FileSystem.FileExists(src) Then
            Using objStream As New System.IO.FileStream(src, IO.FileMode.Open)
                objSerializer = New XmlSerializer(GetType(clsSettings))

                settings = DirectCast(objSerializer.Deserialize(objStream), clsSettings)

            End Using

        End If

        For Each el In settings.Accounts
            Console.WriteLine($"{el.User} {el.Pw}")

        Next

    End Sub

    Public Sub Main()
        Dim src = "C:\temp\SodahSample.xml"
        X(src)

        Console.ReadLine()

    End Sub

End Module

To get the output

tralala tralala
triliki trierer

So there are two things to make sure of: first, that your file encoding matches what is in the XML declaration, and secondly that the classes you declare conform to what is in the XML document. You might find that using an XSD file helps.

Your classes don't match your XML...try this:

Public Class clsSettings
    <DefaultValue("")>
    Public Property valueA() As String

    <DefaultValue("")>
    Public Property valueB() As String

    <XmlArrayItem("Account")>
    Public Property Accounts() As New List(Of Account)
End Class

Public Class Account
    <DefaultValue("")>
    Public Property User() As String

    <DefaultValue("")>
    Public Property Pw() As String
End Class

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM