xml - 尝试使用 VB.net 序列化和反序列化复杂的 xml 文件

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

我是 Visual Studio 2015 (VB) 的 XML 初学者。 Deserialize 仅适用于 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>

这是我的类(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

她是代码:

    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 作为类粘贴”,则可以让 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"”,因此我使用该编码(使用小端字节序并包括 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有帮助。

关于xml - 尝试使用 VB.net 序列化和反序列化复杂的 xml 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40979723/

相关文章:

android - 如何在 Android Studio 的 xml 中注释掉行)?

django - 如何将 serializers.RelatedField() 添加到 django rest 框架中的 Meta 类字段

javascript - 从 VB.NET 到 JavaScript 通过 WebMethod 获取 SessionID

c# - 使用 Json.Net 的 JObject.FromObject 方法进行序列化时,我可以使用自定义 ContractResolver 吗?

powershell - 如何将参数列表中的类对象传递到另一台计算机并在其上调用函数?

xml - 我什么时候应该使用元素而不是属性?

java - 使用 JAXB 获取子节点中的 XML 数据作为字符串

xml - Reddit 搜索 api - 通过 subreddit 搜索

c# - VB WPF 到 C# WPF

vb.net - 加密/解密数据流?