【问题标题】:trying to serialize and deserialize an complex xml file using VB.net尝试使用 VB.net 序列化和反序列化复杂的 xml 文件
【发布时间】:2016-12-05 17:15:24
【问题描述】:

我是 Visual Studio 2015 (VB) 上的 XML 初学者。反序列化仅适用于 valueA 和 valueB。但是账户是空的。我不明白这个问题。我能做些什么?或者反序列化这个 XML 文件的正确方法是什么,我如何访问 vb 中的 var?谢谢!!!

我已关注 XML 文件:

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

这是我的班级:

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

她是代码:

    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

【问题讨论】:

  • 该 XML 示例是如何创建的?它在几个方面与那些序列化程序设置不匹配。帐户将是空的,因为没有列表实例来存储任何内容 - 它只是在该代码中声明为列表。此外,将密码存储为文本也是一个非常糟糕的主意。

标签: xml vb.net serialization visual-studio-2015


【解决方案1】:

如果您在粘贴缓冲区中有 XML 并选择“编辑”->“选择性粘贴”->“将 XML 粘贴为类”,您可以让 Visual Studio 为您的 XML 创建类。我在一个新的类文件中做了这个并得到了

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

请注意,它使用最小大小的数据类型来存储它在粘贴中看到的内容,因此“ValueA”之类的内容已设置为Byte 类型。你可能想改变这些。

接下来,我注意到您的 XML 声明包含“encoding="utf-16"”,因此我小心地使用该编码保存了您的示例数据(使用 little-endian 并包括 BOM)。我曾尝试不这样做,但出现错误“XML 文档 (0,0) 中存在错误”。

完成所有设置后,我使用了一个简单的控制台应用程序:

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

获取输出

tralala tralala
triliki trierer

所以有两件事要确保:首先,您的文件编码与 XML 声明中的内容相匹配,其次,您声明的类与 XML 文档中的内容一致。您可能会发现使用 XSD file 会有所帮助。

【讨论】:

    【解决方案2】:

    您的类与您的 XML 不匹配...试试这个:

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-10-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多